235 lines
9.8 KiB
TypeScript
235 lines
9.8 KiB
TypeScript
import { FIGURE_UNLOCK_CONDITION, ITEM_CHANGE_REASON, REDIS_KEY, STATUS, TASK_TYPE, HERO_SYSTEM_TYPE, LINEUP_NUM } from "../../consts";
|
|
import { SkinModel } from "../../db/Skin";
|
|
import { HeroModel, HeroSkin, HeroType, HeroUpdate } from "../../db/Hero";
|
|
import { RoleModel, RoleType, RoleUpdate } from "../../db/Role";
|
|
import { SkinUpdate } from "../../db/Skin";
|
|
import { Figure, TopHero } from "../../domain/dbGeneral";
|
|
import { TaskListReturn } from "../../domain/roleField/task";
|
|
import { GuildModel, GuildType } from "../../db/Guild";
|
|
import { PvpDefenseModel } from "../../db/PvpDefense";
|
|
import { pick } from "underscore";
|
|
import { calculatetopLineup } from "../../pubUtils/util";
|
|
import { nowSeconds } from "../../pubUtils/timeUtil";
|
|
import { saveCeChangeLog } from "../../pubUtils/logUtil";
|
|
import { getRandSingleEelm, reduceCe, resResult } from "../../pubUtils/util";
|
|
import { AttributeCal } from "../../domain/roleField/attribute";
|
|
import { CreateHeroParam, HeroParam, HeroShowParam } from "../../domain/roleField/hero";
|
|
import { pinus } from "pinus";
|
|
import { Rank } from "../rankService";
|
|
import { checkTaskInCreateHero } from "../task/taskService";
|
|
import { ItemInter, RewardInter } from "../../pubUtils/interface";
|
|
import { transPiece } from "./util";
|
|
import { getInitHeroById } from "../roleService";
|
|
import { addItems, combineFigureInfo, unlockFigure, unlockFigureWithoutSave } from "./rewardService";
|
|
import { gameData } from "../../pubUtils/data";
|
|
import { CalCe } from "./calCe";
|
|
import RoleCe, { RoleCeModel, RoleCeUpdate } from "../../db/RoleCe";
|
|
|
|
export class CreateHeroes {
|
|
private roleId: string;
|
|
private roleName: string;
|
|
private serverId: number;
|
|
private incHeroNum: number = 0;
|
|
private incRoleCe: number = 0;
|
|
private role: RoleType;
|
|
private guild: GuildType;
|
|
|
|
// 推送信息
|
|
private figureConditions: { type: FIGURE_UNLOCK_CONDITION, paramHid: number }[] = [];
|
|
private skins: SkinUpdate[] = [];
|
|
private heroes: HeroUpdate[] = [];
|
|
private roleCe: RoleCeUpdate = {};
|
|
private resultHeroes: HeroType[] = [];
|
|
private topLineup: TopHero[] = [];
|
|
private topLineupCe: number = 0;
|
|
|
|
constructor(roleId: string, roleName: string, serverId: number) {
|
|
this.roleId = roleId;
|
|
this.roleName = roleName;
|
|
this.serverId = serverId;
|
|
}
|
|
|
|
public setRole(role: RoleType) {
|
|
this.role = role;
|
|
}
|
|
|
|
public async getRole() {
|
|
if(!this.role) {
|
|
this.role = await RoleModel.findByRoleId(this.roleId);
|
|
this.topLineup = this.role.topLineup;
|
|
this.topLineupCe = this.role.topLineupCe;
|
|
}
|
|
return this.role;
|
|
}
|
|
|
|
public async createHeroes(hids: number[]) {
|
|
let { roleId, roleName } = this;
|
|
for(let hid of hids) {
|
|
let initSkin = SkinModel.getInitInfo(hid);
|
|
let initHero = HeroModel.getInitInfo(hid, { roleId, roleName, skins: [new HeroSkin(initSkin)] });
|
|
this.heroes.push(initHero);
|
|
this.skins.push(initSkin);
|
|
this.figureConditions.push({ type: FIGURE_UNLOCK_CONDITION.GET_HERO, paramHid: hid });
|
|
this.incHeroNum ++;
|
|
}
|
|
await this.calCe(); // 计算战力
|
|
await this.saveCeToDb();
|
|
}
|
|
|
|
private async calCe() {
|
|
let role = await this.getRole();
|
|
let calCe = new CalCe();
|
|
calCe.setInitHero(role, this.heroes); // 设置武将初始信息
|
|
let ces = calCe.calHeroCe(); // 战力
|
|
for(let hero of this.heroes) {
|
|
hero.ce = ces.get(hero.hid)||0;
|
|
hero.historyCe = hero.ce;
|
|
this.incRoleCe += hero.ce;
|
|
}
|
|
this.roleCe = calCe.getRoleCeTable();
|
|
}
|
|
|
|
// 更新战力相关的各个表
|
|
private async saveCeToDb() {
|
|
let role = await this.getRole();
|
|
// 更新武将表
|
|
for(let hero of this.heroes) {
|
|
let resultHero = await HeroModel.createHero(hero);
|
|
this.resultHeroes.push(resultHero);
|
|
await calculatetopLineup(role, resultHero.hid, resultHero.ce, resultHero._id);
|
|
}
|
|
this.heroes = [];
|
|
// 更新role表
|
|
role = await RoleModel.incRoleInfo(this.roleId, { heroNum: this.incHeroNum, ce: this.incRoleCe }, { heroNumUpdatedAt: nowSeconds(), });
|
|
this.setRole(role);
|
|
// 更新roleCe表
|
|
await RoleCeModel.updateRoleCe(this.roleId, this.roleCe);
|
|
// 更新皮肤表
|
|
await SkinModel.insertSkins(this.roleId, this.roleName, this.skins)
|
|
// 更新guild表
|
|
if(role.hasGuild) {
|
|
this.guild = await GuildModel.updateCe(this.roleId, this.incRoleCe, true); // 公会更新战力
|
|
}
|
|
for(let { hid, ce } of this.resultHeroes) {
|
|
await PvpDefenseModel.updateCe(this.roleId, hid, ce); // 更新pvp防守阵战力
|
|
}
|
|
saveCeChangeLog(role, this.incRoleCe, role.ce, HERO_SYSTEM_TYPE.INIT, this.resultHeroes.map(cur => cur.hid));
|
|
}
|
|
|
|
public async updateRedisRank() {
|
|
let { serverId, roleId, resultHeroes, role } = this;
|
|
// 更新军团信息
|
|
if(this.guild) {
|
|
let r = new Rank(REDIS_KEY.GUILD_INFO, { guildCode: this.guild.code });
|
|
await r.generParamAndSet(REDIS_KEY.GUILD_INFO, { guildCode: this.guild.code }, { guild: this.guild });
|
|
}
|
|
// 武将数量
|
|
if(this.incHeroNum > 0) {
|
|
let r = new Rank(REDIS_KEY.HERO_NUM_RANK, { serverId });
|
|
await r.setRankWithRoleInfo(roleId, role.heroNum, role.heroNumUpdatedAt, role);
|
|
}
|
|
|
|
// 最强阵容
|
|
let r = new Rank(REDIS_KEY.TOP_LINEUP_RANK, { serverId });
|
|
await r.setRankWithRoleInfo(roleId, reduceCe(role.topLineupCe), 0, role);
|
|
|
|
// 最强武将
|
|
for(let hero of resultHeroes) {
|
|
let r2 = new Rank(REDIS_KEY.TOP_HERO_RANK, { serverId });
|
|
await r2.setRankWithHeroInfo(roleId, hero.hid, hero.ce, 0, hero);
|
|
|
|
let r4 = new Rank(REDIS_KEY.HERO_RANK, { serverId, hid: hero.hid });
|
|
await r4.setRankWithHeroInfo(roleId, hero.hid, hero.ce, 0, hero);
|
|
}
|
|
// 总战力
|
|
let r3 = new Rank(REDIS_KEY.SUM_CE_RANK, { serverId });
|
|
await r3.setRankWithRoleInfo(roleId, reduceCe(role.ce), 0, role);
|
|
|
|
// 更新最强五人阵容信息
|
|
let r5 = new Rank(REDIS_KEY.TOP_LINEUP_INFO, { serverId });
|
|
await r5.generParamAndSet(REDIS_KEY.TOP_LINEUP_INFO, { roleId }, { role });
|
|
}
|
|
|
|
public async pushMessage(sid: string) {
|
|
let role = await this.getRole();
|
|
let uids = [{ uid: this.roleId, sid }];
|
|
pinus.app.get('channelService').pushMessageByUids('onPlayerCeUpdate', resResult(STATUS.SUCCESS, { ce: role.ce, heros: this.resultHeroes.map(({ hid, ce }) => ({ hid, ce, incHeroCe: ce})), topLineupCe: role.topLineupCe}), uids);
|
|
|
|
pinus.app.get('channelService').pushMessageByUids('onHeroSkinChange', resResult(STATUS.SUCCESS, this.getSkinPushMsg()), uids);
|
|
pinus.app.get('channelService').pushMessageByUids('onHeroUpdate', resResult(STATUS.SUCCESS, { heroes: this.getResultHeroes() }), uids);
|
|
checkTaskInCreateHero(this.serverId, this.roleId, sid, this.incHeroNum, this.resultHeroes);
|
|
await unlockFigure(sid, this.roleId, this.figureConditions);
|
|
}
|
|
|
|
private getSkinPushMsg() {
|
|
let skinPushMessages: {heros: {skins: HeroSkin[], hid: number}[], skins: {id: number, hid: number, inc: number, reason: number }[]} = { heros: [], skins:[] }; // 皮肤推送信息
|
|
for(let { hid, skins } of this.resultHeroes) {
|
|
skinPushMessages.heros.push({ hid, skins });
|
|
}
|
|
for(let { id, hid } of this.skins) {
|
|
skinPushMessages.skins.push({ id, hid, inc: 1, reason: ITEM_CHANGE_REASON.GET_HERO_UNLOCK_SKIN })
|
|
}
|
|
return skinPushMessages;
|
|
}
|
|
|
|
public getResultHeroes() {
|
|
return this.resultHeroes;
|
|
}
|
|
|
|
public getShowHeroes() {
|
|
return this.resultHeroes.map(cur => {
|
|
let hero = new HeroShowParam(cur);
|
|
return { ...hero, ce: reduceCe(cur.ce)}
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* 创建多个武将
|
|
* @param roleId
|
|
* @param sid
|
|
* @param serverId
|
|
* @param heroInfo
|
|
*/
|
|
export async function createHeroes(roleId: string, roleName: string, sid: string, serverId: number, heroInfo: CreateHeroParam[]) {
|
|
let hids = heroInfo.map(cur => cur.hid);
|
|
let userHeroesMap = await HeroModel.findMapByHidRange(hids, roleId);
|
|
|
|
let createHids: number[] = [], pieces: ItemInter[] = [];
|
|
for (let h of heroInfo) {
|
|
let heroCount = h.count || 1;
|
|
if (userHeroesMap.has(h.hid)) {
|
|
let { pieceId, count } = transPiece(h.hid);
|
|
pieces.push({ id: pieceId, count: count * heroCount });
|
|
} else {
|
|
createHids.push(h.hid);
|
|
userHeroesMap.set(h.hid, null);
|
|
if (heroCount > 1) {
|
|
let { pieceId, count } = transPiece(h.hid);
|
|
pieces.push({ id: pieceId, count: count * (heroCount - 1) });
|
|
}
|
|
}
|
|
}
|
|
|
|
let resultHeroes: HeroType[] = [], resultItems: RewardInter[] = [], heroes: HeroShowParam[] = [];
|
|
if (createHids.length > 0) {
|
|
let createHero = new CreateHeroes(roleId, roleName, serverId);
|
|
await createHero.createHeroes(createHids);
|
|
await createHero.pushMessage(sid);
|
|
await createHero.updateRedisRank();
|
|
heroes = createHero.getShowHeroes();
|
|
resultHeroes = createHero.getResultHeroes();
|
|
}
|
|
|
|
if (pieces.length > 0) {
|
|
let goods = await addItems(roleId, roleName, sid, pieces, ITEM_CHANGE_REASON.HERO_TRANSFER_PIECE);
|
|
resultItems = goods;
|
|
}
|
|
return { heroes, resultHeroes, goods: resultItems }
|
|
}
|
|
|
|
export async function createHero(roleId: string, roleName: string, sid: string, serverId: number, heroInfo: CreateHeroParam) {
|
|
let result = await createHeroes(roleId, roleName, sid, serverId, [heroInfo]);
|
|
return result;
|
|
} |