182 lines
7.0 KiB
TypeScript
182 lines
7.0 KiB
TypeScript
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 } from '../pubUtils/util';
|
|
import { handleFixedReward } from './rewardService';
|
|
import { resResult } from '../pubUtils/util';
|
|
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) {
|
|
bonusReward = await handleFixedReward(roleId, roleName, bonus, 1);
|
|
}
|
|
if (fixReward) {
|
|
towerReward = await handleFixedReward(roleId, roleName, fixReward, 1);
|
|
}
|
|
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 { startLv, 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,
|
|
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;
|
|
} |