922 lines
30 KiB
TypeScript
Raw Permalink Normal View History

2025-04-23 09:34:08 +08:00
import PlayerMgr from "../object/PlayerMgr";
import PaiHangMgr from "../core/PaiHangMgr";
import { BattleType, EEventType, ERaceType, MsgCode } from "../role/EEnum";
import DB from "../utils/DB";
import * as schedule from "node-schedule";
import SKLogger from "../gear/SKLogger";
import Player from "../object/Player";
import SKDataUtil from "../gear/SKDataUtil";
import ActivityDefine from "./ActivityDefine";
import GTimer from "../common/GTimer";
import TeamMgr from "../core/TeamMgr";
import Currency from "../activity/Currency";
import NoticeMgr from "../core/NoticeMgr";
import SpecialEffect from "../object/SpecialEffect";
export default class TianTi {
static shared = new TianTi();
schedule: any;// 定时器:每天更新排行榜
schedule2: any;// 定时器:每月结算奖励
reportlist: any[];
// 奖励列表
JiangLiList: any[];
/**限制击杀表 */
limtlist: any[];
/**定时时间(毫秒单位) */
state_time: any = {
sign_time: 1000, // 通知完2分钟后开始报名
sat_time: 60 * 60 * 1000 *5 // 巅峰对决35分钟
}
/**比赛阶段 */
match_state: any = {
/** 备战-巅峰对决*/
beizhantianti: 1, //
/** 巅峰对决*/
tiantizhan: 2 //
}
/**战斗状态 */
FightState: any = {
Wait: 1, // 等待
FightEnd: 2, // 结束战斗
Fighting: 3, // 等待状态
}
/**赛季 */
season: number;
/**参战队伍 报名加入 */
match_team: any[];
name: any;
player_list: any;
/** 天梯状态 */
activity_state: any;
/**通知时间 */
inform_time: any;
/**比赛阶段 */
game_state: any;
/**奖励 */
goods_award: any[];
/**定时匹配队伍 */
matching_cancel: any;
/**定时调整队伍 */
adjust_cancel: any;
constructor() {
this.JiangLiList = [];//奖励列表
this.reportlist = [];//天梯排行数据
// this.goods_award = [50014, 50015, 10406, 10110, 10609, 10604, 50016, 95142, 50033];//奖励列表
this.goods_award =[];
this.limtlist = [];
this.name = '天梯巅峰战';
/**赛季 */
this.season = 1;
/**参数队伍 */
this.match_team = [];
this.player_list = {};
this.game_state = 0;
}
OnNewDay() {
this.limtlist = [];
}
init() {
this.activity_state = ActivityDefine.activityState.Close;//天梯状态
schedule.scheduleJob("0 0 12 ? * *", () => {
//先更新排行数据
this.reportlist = []; //先清空 //在读取
let sql = `SELECT * FROM qy_tianti;`;
DB.query(sql, (error: any, rows: any) => {
if (error) {
return;
}
for (let i = 0; i < rows.length; i++) {
SKLogger.debug('开始读取天梯数据')
this.reportlist.push({
roleid: rows[i].roleid,
resid: rows[i].resid,
jifen: rows[i].jifen,
name: rows[i].name,
baichang: rows[i].baichang,
shengchang: rows[i].shengchang,
wingId: Number(rows[i].wingId),
effid: rows[i].effid,
})
}
})
// 修改状态为准备报名
this.open();
})
this.schedule2 = schedule.scheduleJob("50 59 23 L * ?", () => {
// var date = new Date(2022,2,15,19,0,0);
// this.schedule2 =schedule.scheduleJob(date, () => {
this.reportlist = []; //先清空 //在读取
let sql = `SELECT * FROM qy_tianti;`;
// let sql = `DELETE FROM qy_tianti;`;
DB.query(sql, (error: any, rows: any) => {
if (error) {
return;
}
for (let i = 0; i < rows.length; i++) {
SKLogger.debug('开始发放天梯奖励')
PlayerMgr.shared.getPlayerByRoleId(rows[i].roleid).addItem(70004, 1200 - (i * 200),true);
let notice:any;
notice.interval=5;
notice.isgm = true
notice.times=3;
notice.type = 3;
NoticeMgr.shared.addNewNotice(notice);
}
});
sql = `DELETE FROM qy_tianti;`;
DB.query(sql, (error: any, rows: any) => {
if (error) {
return;
}
});
})
this.reportlist = []; //先清空 //在读取
let sql = `SELECT * FROM qy_tianti;`;
DB.query(sql, (error: any, rows: any) => {
if (error) {
return;
}
for (let i = 0; i < rows.length; i++) {
this.reportlist.push({
roleid: rows[i].roleid,
resid: rows[i].resid,
jifen: rows[i].jifen,
name: rows[i].name,
baichang: rows[i].baichang,
shengchang: rows[i].shengchang,
wingId: rows[i].wingId,
effid: rows[i].effid,
})
}
SKLogger.debug('读取天梯数据成功!!')
})
//读取兑换奖励
this.JiangLiList = []; //先清空 //在读取
sql = `SELECT * FROM prop_tiantijiangli;`;
DB.query(sql, (error: any, rows: any) => {
if (error) {
SKLogger.debug('读取天梯奖励奖励失败')
return;
}
for (let i = 0; i < rows.length; i++) {
this.JiangLiList.push({
id: rows[i].id,
itemid: rows[i].itemid,
price: rows[i].price,
name: rows[i].name,
des: rows[i].des,
})
}
SKLogger.debug('读取天梯奖励数据成功!!===================================')
})
//读取掉落奖励
this.goods_award = []; //先清空 //在读取
sql = `SELECT * FROM qy_tianti_diaoluo;`;
DB.query(sql, (error: any, rows: any) => {
if (error) {
SKLogger.debug('读取掉落奖励失败')
return;
}
for (let i = 0; i < rows.length; i++) {
this.goods_award.push( rows[i].itemid);
}
})
// this.open();//测试直接开启
}
/**
* -
*/
open() {
this.player_list = {};
this.match_team = [];
this.activity_state = ActivityDefine.activityState.Opening;//报名状态
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,
});
this.inform_time = GTimer.getTime();
// 开始巅峰对决
setTimeout(() => {
this.inform_time = GTimer.getTime();
this.SatPk();
}, 5 * 1000);
SKLogger.info(`活动(${this.name})已经开启!${this.name}状态改变 当前状态:开始报名`);
}
/**
* -
*/
SatPk() {
// 即将关闭活动定时
setTimeout(() => {
this.inform_time = GTimer.getTime();
// 即将关闭(活动结束前两分钟通知)
this.readyClose();
}, this.state_time.sat_time - (2 * 60 * 1000));
// 关闭活动定时
setTimeout(() => {
this.inform_time = GTimer.getTime();
// 活动结束-关闭
this.close();
}, this.state_time.sat_time);
// 通知队伍中玩家比赛状态-巅峰对决
// for (const teamId in this.player_list) {
// if (this.player_list.hasOwnProperty(teamId)) {
// this.sayStage(TeamMgr.shared.getTeamInfo(teamId), this.match_state.sat, this.state_time.sat_time);
// }
// }
// 开始比赛
this.matching();
}
/**
*
*/
matching() {
SKLogger.info(`天梯状态改变 当前状态:开始比赛`);
this.checkMatch(this.match_team);
//'*'表示通配符,匹配任意,当秒是'*'时,表示任意秒数都触发,其它类推
// 6个占位符从左到右分别代表秒、分、时、日、月、周几
this.matching_cancel = schedule.scheduleJob("0/10 * * * * ? ", () => {
this.checkMatch(this.match_team);
})
this.adjust_cancel = schedule.scheduleJob("0/10 * * * * ? ", () => {
this.checkFightTime();
})
}
/**
* 10
*/
checkFightTime() {
let nowtime = Date.now();
for (const teaminfo of this.match_team) {
if (teaminfo.fight_state == this.FightState.FightEnd) {
if (nowtime - teaminfo.fight_end_time > 10 * 1000) {
teaminfo.fight_end_time = 0;
teaminfo.fight_state = this.FightState.Wait;
}
}
}
}
/**
*
*/
checkMatch(match: any) {
SKLogger.debug('匹配队伍进行战斗:' + match.length);
if (match.length <= 1) {
// this.close();
return;
} else {
let peak_team_all: any = [];
let peak_team: any = [];
let num = Math.floor(match.length / 2);//判断队伍是否对战数量
let flag = true;
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() * match.length);
if (peak_team_all.indexOf(match[ran]) != -1 || match[ran].fight_state != this.FightState.Wait) {
continue;
}
peak_team.push(match[ran]);
peak_team_all.push(match[ran]);
} else {
flag = false;
}
}
if (peak_team.length >= 2) {
if (peak_team[0].teamid != peak_team[1].teamid) {
this.beforeFight(peak_team[0], peak_team[1]);
}
}
peak_team = [];
flag = true;
}
}
}
// 战斗开始之前的 10秒
beforeFight(t1: any, t2: 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);
if (this.hasLimt(satRole.onlyid)) {//存在记录
for (let index = 0; index < this.limtlist.length; index++) {
const lim = this.limtlist[index]; //限制
if (lim.roleid == satRole.onlyid) {
if (lim.num >= 10) {
member.send('s2c_notice', {
strRichText: '已达到最大匹配次数!'
})
// return;
} else {
lim.num++;
}
}
}
} else {//没有记录
let info: any = {};
info.roleid = satRole.onlyid;
info.num = 0;
this.limtlist.push(info)
}
}
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);
if (this.hasLimt(satRole.onlyid)) {//存在记录
for (let index = 0; index < this.limtlist.length; index++) {
const lim = this.limtlist[index]; //限制
if (lim.roleid == satRole.onlyid) {
if (lim.num >= 10) {
member.send('s2c_notice', {
strRichText: '已达到最大匹配次数!'
})
// return;
} else {
lim.num++;
}
}
}
} else {//没有记录
let info: any = {};
info.roleid = satRole.onlyid;
info.num = 0;
this.limtlist.push(info)
}
}
TeamMgr.shared.broadcast(t1.teamid, 's2c_tiantisat_match', {
teamS: selfTeam,
teamE: enemyTeam,
});
TeamMgr.shared.broadcast(t2.teamid, 's2c_tiantisat_match', {
teamS: enemyTeam,
teamE: selfTeam,
});
t1.fight_state = this.FightState.Fighting;
t2.fight_state = this.FightState.Fighting;
setTimeout(() => {
this.startFight(t1, t2);
}, 9 * 1000);
}
}
hasLimt(roleid: any): boolean {
for (let rid of this.limtlist) {
if (rid.roleid == roleid) {
return true;
}
}
return false;
}
/**
*
* @param t1
* @param t2
*/
startFight(t1: any, t2: any) {
let team = TeamMgr.shared.getTeamInfo(t1.teamid);
let eteam = TeamMgr.shared.getTeamInfo(t2.teamid);
delete this.player_list[t1.teamid];
delete this.player_list[t2.teamid];
for (let i = 0; i < this.match_team.length; i++) {
let info: any = this.match_team[i];
if (info.teamid != t1.teamid) {
continue;
}
this.match_team.splice(i, 1);
break;
}
for (let i = 0; i < this.match_team.length; i++) {
let info: any = this.match_team[i];
if (info.teamid != t2.teamid) {
continue;
}
this.match_team.splice(i, 1);
break;
}
if (team && eteam) {
let eonlyid = eteam.leader.onlyid;
team.leader.playerBattle(eonlyid, BattleType.TianTIFight);
}
}
/**
*
* @param team
*/
sayStage(team: any, type: number, countDown: number) {
if (team != null) {
countDown = countDown - (GTimer.getTime() - this.inform_time);
for (let i = 0; i < team.playerlist.length; i++) {
const mem = team.playerlist[i];
// 通知前端改为巅峰
if (type == this.match_state.prepare_sat) {
let teamInfo = this.player_list[team.teamid];
if (teamInfo) {
mem.send('s2c_update_say_peak', {
score: teamInfo.peak
})
}
}
// 通知前端更改比赛状态
mem.send('s2c_say_stage', {
type: type,
countDown: countDown,
});
}
}
}
/**
*
*/
readyClose() {
this.activity_state = ActivityDefine.activityState.ReadyClose;
// 关闭定时调整队伍
this.adjust_cancel.cancel();
// 关闭定时匹配队伍
this.matching_cancel.cancel();
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,
});
}
/**
*
*/
close() {
if (this.activity_state == ActivityDefine.activityState.Close) {
return;
}
// 关闭定时调整队伍
if (this.adjust_cancel != undefined && this.adjust_cancel != null) {
this.adjust_cancel.cancel();
}
// 关闭定时匹配队伍
if (this.matching_cancel != undefined && this.matching_cancel != null) {
this.matching_cancel.cancel();
}
// 活动状态
this.activity_state = ActivityDefine.activityState.Close;
// 清理在场队伍跳转长安
for (const teamId in this.player_list) {
if (this.player_list.hasOwnProperty(teamId)) {
let team = this.player_list[teamId];
this.leaveSat(PlayerMgr.shared.getPlayerByRoleId(team.pid), teamId);
}
}
// 清理数据
this.match_team = [];
this.player_list = {};
}
/**
*
*/
leaveSat(player: any, teamId: any) {
if (player) {
let team = this.player_list[teamId];
if (team != null && team != undefined) {
if (team.pid == player.roleid) {
delete this.player_list[teamId];
} else {
player.send_notice("您不是队长不可以次操作!");
player.send('s2c_leave_sat', {
code: MsgCode.FAILED
});
return;
}
}
for (let i = 0; i < this.match_team.length; i++) {
let info: any = this.match_team[i];
if (info.teamid != teamId) {
continue;
}
this.match_team.splice(i, 1);
break;
}
// 通知当前队伍成员将证道大会标题取消显示
// let team_list = TeamMgr.shared.getTeamInfo(teamId);
// if (team_list) {
// for (const member of team_list.playerlist) {
// member.send('s2c_leave_sat', {
// code: MsgCode.SUCCESS
// });
// }
// }
}
}
/**
*
* @param teamid
*/
getMatchTeamInfo(teamid: any): any {
for (let teaminfo of this.match_team) {
if (teaminfo.teamid == teamid) {
return teaminfo;
}
}
return null;
}
/**
*
* @param playid
* @param isWin 1 0
*/
sendReward(playid: any, isWin: any) {
let play = PlayerMgr.shared.getPlayerByOnlyId(playid);
if (play) {
// 获取队伍战斗分数(胜利 人数 * 10失败 人数 * 5
let score = isWin == 1 ? 100 : 50;
play.tianti_integral+=score;
// 更新参数队伍的积分
// let dataScore = this.updateMatchScore(isWin, score, teamId, type, team, teamInfo);
// 获取随机道具
let item = this.goods_award[Math.floor((Math.random() * this.goods_award.length))];
let exp = play.level * 6000 + play.relive * 50000;
let pExp = Math.floor(exp * 1.2);
play.addExp(exp);
// 随机发送几个道具
play.addItem(item, Math.floor(Math.random() * 3) + 1, false, "天梯奖励!")
play.curPet && (play.curPet.addExp(pExp));
// 天梯积分积分
play.tianti_integral += score;
let baichang = isWin == 1 ? 0 : 1;;
let shengchang = isWin == 1 ? 1 : 0;
for (const key in this.reportlist) {
if (Object.prototype.hasOwnProperty.call(this.reportlist, key)) {
const element = this.reportlist[key];
if (element.roleid == play.roleid) {
let effid = SpecialEffect.shared.getSuiEffect(play.roleid);
element.jifen += score;
baichang = element.baichang += baichang;
element.baichang = baichang;
shengchang = element.shengchang += shengchang;
element.shengchang = shengchang;
element.wingId = play.wingId,
element.effid = effid
}
}
}
//更新数据库
let effid = SpecialEffect.shared.getSuiEffect(play.roleid);
DB.tiantidata(play, play.tianti_integral, baichang, shengchang, effid, () => {
});
// 通知前端更新积分信息
play.send('s2c_match_battles', {
type: 3, // 1 元魔 0 证道
isWin: isWin, // 1 胜利 0 失败
icon: item, // 图标
exp: exp, // 人物经验
petExp: pExp, // 宠物经验
score: score, // 当前获得分数
peak: 0, // 当前巅峰积分
satScore: 0, // 队伍证道积分
matchScore: 0 // 队伍元魔积分
});
}
// 巅峰对决巅峰积分小于等于0清理出场
// if (type == 0 && isWin == 0) {
// let info = this.player_list[teamId];
// if (info.peak <= 0) {
// for (const member of team.playerlist) {
// member.send_notice("由于你所在队伍的巅峰积分不足,失去继续比赛资格!")
// }
// this.leaveSat(PlayerMgr.shared.getPlayerByRoleId(info.pid), teamId);
// // 当前队伍小于2个队伍直接结束活动
// let count_player: number = Object.keys(this.player_list).length
// if (count_player <= 1) {
// this.close();
// }
// }
// }
}
/**
*
* @param isWin 1 0
* @param score
* @param teamId ID
* @param type 1 0
*/
updateMatchScore(isWin: number, score: number, teamId: any, type: number, team: any, player_team: any): any {
let data: any = {};
if (type == 1) {
player_team.magic_score += score;
} else {
player_team.sat_score += score;
if (isWin == 1) {
player_team.peak += 50;
} else {
player_team.peak -= 50;
}
}
// 巅峰积分
data.peak = player_team.peak;
// 元魔积分
data.satScore = player_team.sat_score;
// 证道积分
data.matchScore = player_team.magic_score;
// 更新 队伍积分状态集合
this.player_list[teamId] = {
name: team.leader.name + '的队伍',
pid: team.leader.roleid, // 队长角色编号
teamid: teamId, // 队伍编号
magic_score: data.matchScore, // 元魔积分
sat_score: data.satScore, // 证道积分
peak: data.peak, // 队伍巅峰积分
num: team.playerlist.length, // 队伍人数
}
return data;
}
//获取天梯数据
getTianTidata(player: any, type: any) {
let report = [];
let selfjifen = 0;
let selfpaiming = 0;
let shengchang = 0;
let baichang = 0;
for (let i = 0; i < this.reportlist.length; i++) {
let items = this.reportlist[i];
report.push({
roleid: items.roleid,
resid: items.resid,
jifen: items.jifen,
name: items.name,
baichang: items.baichang,
shengchang: items.shengchang,
wingId: Number(items.wingId),
effid: items.effid
})
}
report.sort((a, b) => { return b.jifen - a.jifen });//排序
for (const key in report) {
if (Object.prototype.hasOwnProperty.call(report, key)) {
const element = report[key];
if (element.roleid == player.roleid) {
selfjifen = element.jifen;
selfpaiming = Number(key) + 1;
shengchang = element.shengchang;
baichang = element.baichang;
break;
}
}
}
report.sort((a, b) => {
return a.jifen < b.jifen ? 1 : -1;
});
let frist = report.splice(0, 6);
// 数据发送前端
player.send('s2c_TianTi_info', {
selfjifen: selfjifen,
selfpaiming: selfpaiming,
shengchang: shengchang,
baichang: baichang,
tiantijizhenshifen:player.tianti_integral,
list: SKDataUtil.toJson(frist, "{}")
});
}
//获取天梯奖励数据
getJiangLidata(player: any) {
SKLogger.debug('获取天梯奖励数据')
// 数据发送前端
let report = [];
for (let i = 0; i < this.JiangLiList.length; i++) {
let items = this.JiangLiList[i];
report.push({
id: items.id,
itemid: items.itemid,
price: items.price,
name: items.name,
des: items.des,
})
}
// 数据发送前端
player.send('s2c_TianTijiangli_info', {
jiangli: SKDataUtil.toJson(this.JiangLiList, "{}"),
});
}
report() {
let callback = (ret: any, rows: any) => {
if (ret == MsgCode.SUCCESS) {
for (let i = 0; i < rows.length; i++) {
this.reportlist.push({
sroleid: rows[i].sroleid,
eresid: rows[i].eresid,
eroleid: rows[i].eroleid,
erolename: rows[i].erolename,
iswin: rows[i].iswin,
ranking: rows[i].ranking,
cdate: rows[i].cdate
})
}
}
}
DB.selectReport(callback);
}
/**
*
*/
playerSign(player: any) {
// 天梯没有开启
if (this.activity_state == ActivityDefine.activityState.Close) {
return MsgCode.TIANTI_NOT_OPEN;
}
// // 不在天梯报名时间
// if (this.activity_state != ActivityDefine.activityState.ReadyOpen) {
// return MsgCode.TIANTI_NOT_SIGN_TIME;
// }
let team = TeamMgr.shared.getTeamInfo(player.teamid);
// // 天梯必须3人以上组队参加
// if (team == null || team.playerlist.length < 3) {
// return MsgCode.TIANTI_SIGN_TEAM;
// }
// // 天梯必须3人以上组队参加
// for (let i = 0; i < team.playerlist.length; i++) {
// const mem = team.playerlist[i];
// if (mem.level < 80) {
// return MsgCode.TIANTI_SIGN_LEVEL_80;
// }
// }
// 只能队长报名
if (team.leader.roleid != player.roleid) {
return MsgCode.SIGN_TEAM_LEADER;
}
if (this.player_list[player.teamid] != null) {
return MsgCode.SIGN_ALREADY;
}
SKLogger.debug('天梯报名成功')
this.player_list[player.teamid] = {
name: player.name + '的队伍',
pid: player.roleid, // 队长角色编号
teamid: player.teamid, // 队伍编号
peak: 0, // 队伍巅峰积分\
num: team.playerlist.length,// 队伍人数
}
// this.sayStage(team, this.match_state.beizhantianti, this.state_time.sign_time)
this.matchTeam(team);
return MsgCode.SUCCESS;
}
matchTeam(team: any) {
let team_data: any = {};
team_data.teamid = team.teamid; // 队伍编号
team_data.wtime = 0;
team_data.ltime = 0;
team_data.fight_state = this.FightState.Wait;
team_data.fight_end_time = 0;
team_data.battle_index = 0;
this.match_team.push(team_data);
}
/**现金奖励 */
starCurrency(battle: any, task_name: string) {
if (battle != null && battle.campA != undefined) {
for (let role of battle.campA.broles) {
// 如果是玩家
if (role.living_type == 1) {
let player = PlayerMgr.shared.getPlayerByOnlyId(role.onlyid)
if (player) {
Currency.shared.obtain_currency(player, task_name)
}
}
}
}
}
}