Files
ZYZ/game-server/app/services/battleService.ts
2020-10-22 11:05:49 +08:00

186 lines
7.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { HeroModel } from './../db/Hero';
import { HangUpRecordModel } from './../db/HangUpRecord';
import { ChannelService } from 'pinus';
import { HANG_UP_CONSTS } from './../consts/consts';
import { BattleRecordModel } from './../db/BattleRecord';
import { TowerRecordModel } from './../db/TowerRecord';
import { RoleModel } from './../db/Role';
import { getHeroInfoById, getJobInfoById, getTowerDataByLv } from "../pubUtils/gamedata"
import { decodeArrayStr, shouldRefresh, resResult } from '../pubUtils/util';
import { handleFixedReward } from './rewardService';
import { STATUS } from '../consts/statusCode';
export async function checkTowerWar(roleId: string, battleId: number, heroes: Array<number>) {
const battleIdStr = `${battleId}`;
let { towerLv } = await RoleModel.findByRoleId(roleId);
const towerInfo = getTowerDataByLv(towerLv);
if (!towerInfo) {
console.error(`天梯层数异常lv ${towerLv} by ${roleId}`);
return { status: -1, resResult: resResult(STATUS.TOWER_INFO_NOT_FOUND) };
}
const warIds = decodeArrayStr(towerInfo.warIds) || [];
if (warIds.indexOf(battleIdStr) === -1) {
return { status: -1, resResult: resResult(STATUS.TOWER_WRONG_BATTLE_ID) };
}
let { heroes: recHeroes = [], warStatus = [] } = await TowerRecordModel.getRecordByLv(roleId, towerLv);
for (let hid of heroes) {
if (recHeroes.indexOf(hid) !== -1) {
return { status: -1, resResult: resResult(STATUS.TOWER_DUPLICATE_HERO) };
}
}
const curWarStatus = warStatus.find(elem => elem.warId == battleId);
if (curWarStatus.status) {
return { status: -1, resResult: resResult(STATUS.TOWER_DUPLICATE_CHALLENGE) };
}
return { status: 0, data: {
heroes: recHeroes, warStatus: curWarStatus
}};
}
export async function towerBattleEnd(channelService: ChannelService, sid: string, roleId: string, battleCode: string, battleId: number, succeed: boolean, heroes: Array<number>) {
if (succeed) {
let battleRec = await BattleRecordModel.getBattleRecordByCode(battleCode);
if (battleRec.battleId != battleId) {
return { status: -1, resResult: resResult(STATUS.BATTLE_ID_NOT_MATCH) };
}
let { towerLv, roleName } = await RoleModel.findByRoleId(roleId);
let { warStatus, heroes: recHeroes } = await TowerRecordModel.getRecordByLv(roleId, towerLv);
for (let hid of heroes) {
if (recHeroes.indexOf(hid) !== -1) {
return { status: -1, resResult: resResult(STATUS.TOWER_DUPLICATE_CHALLENGE) };
}
}
let inc = 1;
warStatus.forEach(st => {
if (st.warId !== battleId && st.status === false) {
inc = 0;
}
})
let newRec = await TowerRecordModel.updateRecord(roleId, towerLv, battleCode, battleId, heroes, inc);
let bonusReward = null;
let towerReward = null;
if (inc === 1) {
await RoleModel.towerLvUp(roleId);
const nextTowerInfo = getTowerDataByLv(towerLv + 1);
if (nextTowerInfo) {
const { warIds } = nextTowerInfo;
const sts = decodeArrayStr(warIds).map(id => {
return {warId: parseInt(id), status: false};
});
await TowerRecordModel.createRecord({roleId, lv: towerLv + 1, warStatus: sts});
}
const { bonus, fixReward } = getTowerDataByLv(towerLv);
if (bonus) {
let result = await handleFixedReward(roleId, roleName, bonus, 1);
bonusReward = result.goods;
}
if (fixReward) {
let result = await handleFixedReward(roleId, roleName, fixReward, 1);
towerReward = result.goods;
}
if (towerLv + 1 >= HANG_UP_CONSTS.ENABLE_LV) {
await startHangUp(roleId, roleName);
channelService.pushMessageByUids('hangUpEnable', {code: 200, data: {enable: true}}, [{uid: roleId, sid}]);
}
}
return {
status: 0,
data: {
newRec,
bonusReward, towerReward,
towerStatus: !!inc
}
};
}
}
async function startHangUp(roleId: string, roleName: string) {
await HangUpRecordModel.initRecord(roleId, roleName);
}
export async function calcuHangUpReward(roleId: string, speedUp = false, speedUpCnt = 1, curTime = new Date()) {
let { towerLv, hangUpSpdUpCnt, lastSpdUpTime } = await RoleModel.findByRoleId(roleId);
let { startTime} = await HangUpRecordModel.getCurRec(roleId);
let towerInfo = getTowerDataByLv(towerLv - 1); // towerLv 是当前层,奖励计算按照已经通过的层,即上一层
let multi = 1; // 结算奖励的倍数,受最大时间限制
let multiReal = 1; // 距开始挂机实际过去的时间单位
if (speedUp) {
if (hangUpSpdUpCnt >= speedUpCnt || shouldRefresh(lastSpdUpTime, new Date, HANG_UP_CONSTS.REFRESH_TIME, 1)) {
multi = speedUpCnt;
} else {
multi = 0;
}
} else {
let deltaTime = curTime.getTime() - startTime.getTime();
multiReal = Math.floor(deltaTime / HANG_UP_CONSTS.UNIT_TIME);
if (deltaTime > HANG_UP_CONSTS.MAX_TIME) deltaTime = HANG_UP_CONSTS.MAX_TIME;
multi = Math.floor(deltaTime / HANG_UP_CONSTS.UNIT_TIME);
}
return {
endLv: towerLv - 1,
startTime,
endTime: new Date(startTime.getTime() + multiReal * HANG_UP_CONSTS.UNIT_TIME),
timeReward: towerInfo.timeReward,
multi
};
}
async function checkCond(roleId: string, heroes, type: number, parm: number, cnt: number) {
let heroCnt = 0;
switch (type) {
case 1:
for(let hid of heroes) {
const rec = await HeroModel.findByHidAndRole(hid, roleId);
if (rec.star >= parm) {
heroCnt++;
}
}
break;
case 2:
for(let hid of heroes) {
const hInfo = getHeroInfoById(hid);
if (hInfo.camp === parm) {
heroCnt++;
}
}
break;
case 3:
for(let hid of heroes) {
const hInfo = getHeroInfoById(hid);
if (getJobInfoById(hInfo.jobid) === parm) {
heroCnt++;
}
}
break;
default:
break;
}
if (heroCnt >= cnt) {
return true;
}
return false;
}
export async function checkTaskConditions(roleId: string, heroes: Array<number>, conditionsStr: string) {
const condArr = conditionsStr.split('|');
if (condArr.length < 1) return false;
let res = true;
for (let cond of condArr) {
const condDetail = cond.split('&');
if (condDetail && condDetail.length === 3) {
const checkRes = await checkCond(roleId, heroes, parseInt(condDetail[0]), parseInt(condDetail[1]), parseInt(condDetail[2]))
if (!checkRes) {
res = false;
break;
}
}
}
return res;
}