创建武将
This commit is contained in:
@@ -92,7 +92,6 @@ export class GuildRemote {
|
|||||||
*/
|
*/
|
||||||
private pushMessage(guildCode: string, path: string, message: any) {
|
private pushMessage(guildCode: string, path: string, message: any) {
|
||||||
let channel = this.getChannel(guildCode);
|
let channel = this.getChannel(guildCode);
|
||||||
console.log('##### channel', guildCode, channel)
|
|
||||||
if (!!channel) {
|
if (!!channel) {
|
||||||
channel.pushMessage(path, resResult(STATUS.SUCCESS, message));
|
channel.pushMessage(path, resResult(STATUS.SUCCESS, message));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ import { HeroModel } from '../../../db/Hero';
|
|||||||
import { calAllHeroCe, calPlayerCeAndSave } from '../../../services/playerCeService';
|
import { calAllHeroCe, calPlayerCeAndSave } from '../../../services/playerCeService';
|
||||||
import { SkinModel } from '../../../db/Skin';
|
import { SkinModel } from '../../../db/Skin';
|
||||||
import { PvpDefenseModel } from '../../../db/PvpDefense';
|
import { PvpDefenseModel } from '../../../db/PvpDefense';
|
||||||
import { calculatetopLineup } from '../../../pubUtils/playerCe';
|
import { calculatetopLineup } from '../../../pubUtils/util';
|
||||||
import { createHeroes } from '../../../services/role/createHero';
|
import { createHeroes } from '../../../services/role/createHero';
|
||||||
|
|
||||||
let timer: NodeJS.Timer;
|
let timer: NodeJS.Timer;
|
||||||
|
|||||||
@@ -11,14 +11,14 @@ import { gameData, getHeroExpByLv, getHeroStarByQuality, getHeroWakeByQuality, g
|
|||||||
import { ItemInter, RewardInter } from '../../../pubUtils/interface';
|
import { ItemInter, RewardInter } from '../../../pubUtils/interface';
|
||||||
import { getDropItems, FIGURE_UNLOCK_CONDITION } from '../../../consts/constModules/itemConst'
|
import { getDropItems, FIGURE_UNLOCK_CONDITION } from '../../../consts/constModules/itemConst'
|
||||||
import { pushComposeOrangeHero, pushHeroQualityUpMsg, pushHeroStarMax, pushHeroWakeUp } from '../../../services/chatService';
|
import { pushComposeOrangeHero, pushHeroQualityUpMsg, pushHeroStarMax, pushHeroWakeUp } from '../../../services/chatService';
|
||||||
import { calculatetopLineup } from '../../../pubUtils/playerCe';
|
import { calculatetopLineup } from '../../../pubUtils/util';
|
||||||
import { PvpDefenseModel } from '../../../db/PvpDefense';
|
import { PvpDefenseModel } from '../../../db/PvpDefense';
|
||||||
import { checkTask, checkTaskInHeroQUalityUp, checkTaskInHeroStarUp, checkTaskInHeroTrain, checkTaskInHeroWakeUp } from '../../../services/task/taskService';
|
import { checkTask, checkTaskInHeroQUalityUp, checkTaskInHeroStarUp, checkTaskInHeroTrain, checkTaskInHeroWakeUp } from '../../../services/task/taskService';
|
||||||
import { isNumber, pick } from 'underscore';
|
import { isNumber, pick } from 'underscore';
|
||||||
import { updateEplaces } from '../../../services/equipService';
|
import { updateEplaces } from '../../../services/equipService';
|
||||||
import { addConsumeToHero, checkUnlockTalentCondition, initSkinTalent, updateSkinTalent } from '../../../services/roleService';
|
import { addConsumeToHero, checkUnlockTalentCondition, initSkinTalent, updateSkinTalent } from '../../../services/roleService';
|
||||||
import { JewelModel, jewelUpdate } from '../../../db/Jewel';
|
import { JewelModel, jewelUpdate } from '../../../db/Jewel';
|
||||||
import { CalHeroCe } from '../../../domain/roleField/calCe';
|
import { CalHeroCe } from '../../../services/role/_calCe';
|
||||||
import { HERO, REBORN } from '../../../pubUtils/dicParam';
|
import { HERO, REBORN } from '../../../pubUtils/dicParam';
|
||||||
import { createHero, createHeroes } from '../../../services/role/createHero';
|
import { createHero, createHeroes } from '../../../services/role/createHero';
|
||||||
import { CheckMeterial } from '../../../services/role/checkMaterial';
|
import { CheckMeterial } from '../../../services/role/checkMaterial';
|
||||||
@@ -654,9 +654,8 @@ export class HeroHandler {
|
|||||||
|
|
||||||
let newSkins = initSkinTalent(skins);
|
let newSkins = initSkinTalent(skins);
|
||||||
let dicHeroScroll = getScollByStar(dicHero.quality, dicHero.initialStars, dicHero.quality, 0);
|
let dicHeroScroll = getScollByStar(dicHero.quality, dicHero.initialStars, dicHero.quality, 0);
|
||||||
let initInfo = HeroModel.getInitInfo({
|
let initInfo = HeroModel.getInitInfo(hid, {
|
||||||
job: dicJob.jobid, skins: newSkins, skinId, ce,
|
job: dicJob.jobid, skins: newSkins, skinId, ce,
|
||||||
star: dicHero.initialStars, quality: dicHero.quality,
|
|
||||||
scrollActive: scrollActive,
|
scrollActive: scrollActive,
|
||||||
scrollId: scrollActive? dicHeroScroll.id: 0,
|
scrollId: scrollActive? dicHeroScroll.id: 0,
|
||||||
scrollStar: scrollActive? dicHeroScroll.stars: 0,
|
scrollStar: scrollActive? dicHeroScroll.stars: 0,
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ import * as dicParam from '../../../pubUtils/dicParam';
|
|||||||
import Counter from '../../../db/Counter';
|
import Counter from '../../../db/Counter';
|
||||||
import { UserModel } from '../../../db/User';
|
import { UserModel } from '../../../db/User';
|
||||||
import { checkFilterWords, reportTAEvent, treatRoleName } from '../../../services/sdkService';
|
import { checkFilterWords, reportTAEvent, treatRoleName } from '../../../services/sdkService';
|
||||||
import { CreateHeroes } from '../../../services/role/createHero';
|
import { createHeroes, CreateHeroes } from '../../../services/role/createHero';
|
||||||
|
|
||||||
export default function (app: Application) {
|
export default function (app: Application) {
|
||||||
new HandlerService(app, {});
|
new HandlerService(app, {});
|
||||||
@@ -50,20 +50,8 @@ export class RoleHandler {
|
|||||||
let checkName = await RoleModel.checkName(roleName, serverId);
|
let checkName = await RoleModel.checkName(roleName, serverId);
|
||||||
if (checkName) return resResult(STATUS.NAME_HAS_USED);
|
if (checkName) return resResult(STATUS.NAME_HAS_USED);
|
||||||
|
|
||||||
let initInfos: { role: RoleUpdate, initInfos: {heroInfo: HeroUpdate, skinInfo: SkinUpdate}[], figureInfo: { heads: Figure[], frames: Figure[], spines: Figure[] }}
|
let { resultHeroes: heroes } = await createHeroes(roleId, roleName, sid, serverId, DEFAULT_HEROES.map(hid => ({hid, count: 1})));
|
||||||
= this.app.get('initRoleInfos');
|
role = await RoleModel.updateRoleInfo(roleId, { roleName, hasInit: true });
|
||||||
role = await RoleModel.updateRoleInfo(roleId, {...initInfos.role, roleName, hasInit: true});
|
|
||||||
let createHero = new CreateHeroes(roleId, roleName, serverId);
|
|
||||||
|
|
||||||
let infos = new Map();
|
|
||||||
for(let {heroInfo, skinInfo} of initInfos.initInfos) {
|
|
||||||
infos.set(heroInfo.hid, { heroInfo, skinInfo });
|
|
||||||
}
|
|
||||||
await createHero.createWithInitInfo(infos, initInfos.figureInfo);
|
|
||||||
await createHero.pushMessage(sid);
|
|
||||||
await createHero.updateRedisRank();
|
|
||||||
let heroes = createHero.getResultHeroes();
|
|
||||||
|
|
||||||
session.set('roleName', roleName);
|
session.set('roleName', roleName);
|
||||||
session.push('roleName', () => { });
|
session.push('roleName', () => { });
|
||||||
|
|
||||||
|
|||||||
@@ -5,14 +5,11 @@ import { HeroUpdate } from '../../../db/Hero';
|
|||||||
import { RoleUpdate } from '../../../db/Role';
|
import { RoleUpdate } from '../../../db/Role';
|
||||||
import { SkinUpdate } from '../../../db/Skin';
|
import { SkinUpdate } from '../../../db/Skin';
|
||||||
import { RankFirstModel, RankFirstType } from '../../../db/RankFirst';
|
import { RankFirstModel, RankFirstType } from '../../../db/RankFirst';
|
||||||
import { DEFAULT_HEROES } from '../../../consts';
|
|
||||||
import { Figure } from '../../../domain/dbGeneral';
|
import { Figure } from '../../../domain/dbGeneral';
|
||||||
import { getDefaultRoleInfo } from '../../../services/roleService';
|
|
||||||
import { PVPConfigModel, PVPConfigType } from '../../../db/SystemConfig';
|
import { PVPConfigModel, PVPConfigType } from '../../../db/SystemConfig';
|
||||||
import { treatRoleName, taflush } from '../../../services/sdkService';
|
import { treatRoleName, taflush } from '../../../services/sdkService';
|
||||||
import { getServerMainten, setServerMainten, stopServerMainten } from '../../../services/gmService';
|
import { getServerMainten, setServerMainten, stopServerMainten } from '../../../services/gmService';
|
||||||
import { errlogger } from '../../../util/logger';
|
import { errlogger } from '../../../util/logger';
|
||||||
import { getInitRoleInfo } from '../../../services/role/initRoleService';
|
|
||||||
|
|
||||||
export default function (app: Application) {
|
export default function (app: Application) {
|
||||||
new HandlerService(app, {});
|
new HandlerService(app, {});
|
||||||
@@ -23,16 +20,12 @@ export class RoleRemote {
|
|||||||
|
|
||||||
constructor(private app: Application) {
|
constructor(private app: Application) {
|
||||||
this.app = app;
|
this.app = app;
|
||||||
this.channelService = app.get('channelService');
|
// this.channelService = app.get('channelService');
|
||||||
this.setInitRole();
|
|
||||||
this.loadRankFirst();
|
this.loadRankFirst();
|
||||||
this.initPvpSeasonNum();
|
this.initPvpSeasonNum();
|
||||||
}
|
}
|
||||||
private channelService: ChannelService;
|
// private channelService: ChannelService;
|
||||||
private initHeroes: Map<number, HeroUpdate> = new Map(); // hid => hero
|
|
||||||
private initRole: RoleUpdate = {};
|
|
||||||
private initSkins: Map<number, SkinUpdate> = new Map(); // hid => skin
|
|
||||||
private figureInfo: {heads: Figure[], frames: Figure[], spines: Figure[]};
|
|
||||||
private rankFirstRewards: Map<number, Map<number, RankFirstType>> = new Map();
|
private rankFirstRewards: Map<number, Map<number, RankFirstType>> = new Map();
|
||||||
|
|
||||||
private async loadRankFirst() {
|
private async loadRankFirst() {
|
||||||
@@ -68,76 +61,6 @@ export class RoleRemote {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public setInitRole() {
|
|
||||||
try {
|
|
||||||
let result = getInitRoleInfo();
|
|
||||||
let { role, heroes, skins, figureInfo } = result;
|
|
||||||
for(let hero of heroes) {
|
|
||||||
this.initHeroes.set(hero.hid, hero);
|
|
||||||
}
|
|
||||||
for(let skin of skins) {
|
|
||||||
this.initSkins.set(skin.hid, skin);
|
|
||||||
}
|
|
||||||
this.initRole = role;
|
|
||||||
this.figureInfo = figureInfo;
|
|
||||||
const initRoleInfos = getDefaultRoleInfo(this.initHeroes, this.initSkins, this.initRole, this.figureInfo);
|
|
||||||
this.app.set('initRoleInfos', initRoleInfos);
|
|
||||||
this.app.set('initHeroes', this.initHeroes);
|
|
||||||
this.app.set('initSkins', this.initSkins);
|
|
||||||
} catch(e) {
|
|
||||||
errlogger.error(`remote ${__filename} \n ${e.stack}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public getInitRoleInfos() {
|
|
||||||
try {
|
|
||||||
let initRoleInfos = this.app.get('initRoleInfos');
|
|
||||||
if (!initRoleInfos) {
|
|
||||||
initRoleInfos = getDefaultRoleInfo(this.initHeroes, this.initSkins, this.initRole, this.figureInfo);
|
|
||||||
this.app.set('initRoleInfos', initRoleInfos);
|
|
||||||
}
|
|
||||||
return initRoleInfos;
|
|
||||||
} catch(e) {
|
|
||||||
errlogger.error(`remote ${__filename} \n ${e.stack}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public getInitHeroes() {
|
|
||||||
try {
|
|
||||||
let result: HeroUpdate[] = [];
|
|
||||||
for(let hid of DEFAULT_HEROES) {
|
|
||||||
result.push(this.initHeroes.get(hid));
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
} catch(e) {
|
|
||||||
errlogger.error(`remote ${__filename} \n ${e.stack}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public getInitSkins() {
|
|
||||||
try {
|
|
||||||
let result: SkinUpdate[] = [];
|
|
||||||
for(let hid of DEFAULT_HEROES) {
|
|
||||||
result.push(this.initSkins.get(hid));
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
} catch(e) {
|
|
||||||
errlogger.error(`remote ${__filename} \n ${e.stack}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public getInitHeroById(hid: number) {
|
|
||||||
try {
|
|
||||||
return {
|
|
||||||
heroInfo: this.initHeroes.get(hid),
|
|
||||||
skinInfo: this.initSkins.get(hid)
|
|
||||||
}
|
|
||||||
} catch(e) {
|
|
||||||
errlogger.error(`remote ${__filename} \n ${e.stack}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 重载json资源
|
* 重载json资源
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -61,7 +61,6 @@ export async function getEnemies(oppPlayers: OppPlayer[], winStreakNum: number)
|
|||||||
* @param pLv 我的排名
|
* @param pLv 我的排名
|
||||||
*/
|
*/
|
||||||
export async function refreshEnemies(role: RoleType, seasonNum: number, sumScore: number, score: number, pLv: number) {
|
export async function refreshEnemies(role: RoleType, seasonNum: number, sumScore: number, score: number, pLv: number) {
|
||||||
console.log('#####',seasonNum, sumScore, score, pLv)
|
|
||||||
let { roleId } = role;
|
let { roleId } = role;
|
||||||
let chosenOpps: string[] = [];
|
let chosenOpps: string[] = [];
|
||||||
let pvpHistoryOppParam: PvpOppCreateParam[] = [];
|
let pvpHistoryOppParam: PvpOppCreateParam[] = [];
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { gameData, getHeroStarByQuality, getHeroWakeByQuality } from "../../pubU
|
|||||||
import { DicRandomEffectPool } from "../../pubUtils/dictionary/DicRandomEffectPool";
|
import { DicRandomEffectPool } from "../../pubUtils/dictionary/DicRandomEffectPool";
|
||||||
import { DicSe } from "../../pubUtils/dictionary/DicSe";
|
import { DicSe } from "../../pubUtils/dictionary/DicSe";
|
||||||
import { deepCopy } from "../../pubUtils/util";
|
import { deepCopy } from "../../pubUtils/util";
|
||||||
import { AttributeCal } from "./attribute";
|
import { AttributeCal } from "../../domain/roleField/attribute";
|
||||||
|
|
||||||
export class CalRoleCe {
|
export class CalRoleCe {
|
||||||
private roleInfo: RoleUpdate;
|
private roleInfo: RoleUpdate;
|
||||||
465
game-server/app/services/role/calCe.ts
Normal file
465
game-server/app/services/role/calCe.ts
Normal file
@@ -0,0 +1,465 @@
|
|||||||
|
import { ABI_STAGE, ABI_STAGE_TO_TYPE, ABI_TYPE_MAIN, SEID_TYPE } from "../../consts";
|
||||||
|
import { HeroUpdate } from "../../db/Hero";
|
||||||
|
import { RoleUpdate, Teraph } from "../../db/Role";
|
||||||
|
import { GlobalAttr, HeroAttr, HeroAttrCell, RoleCeType } from "../../db/RoleCe";
|
||||||
|
import { AttributeCal } from "../../domain/roleField/attribute";
|
||||||
|
import { gameData, getHeroStarByQuality, getHeroWakeByQuality, getTeraph } from "../../pubUtils/data";
|
||||||
|
import { DicRandomEffectPool } from "../../pubUtils/dictionary/DicRandomEffectPool";
|
||||||
|
import { DicSe } from "../../pubUtils/dictionary/DicSe";
|
||||||
|
import { addToMap, deepCopy } from "../../pubUtils/util";
|
||||||
|
|
||||||
|
class RoleCe {
|
||||||
|
roleId: string;
|
||||||
|
globalAttrs: Map<number, GlobalMainAttr|GlobalSubAttr> = new Map(); // attrId => GlobalCe
|
||||||
|
heroAttrs: Map<string, HeroMainAttr|HeroSubAttr> = new Map(); // hid+attrId => HeroCe
|
||||||
|
heroAttrsByHid: Map<number, string[]> = new Map(); // hid => [hid+attrId]
|
||||||
|
heroLv: Map<number, number> = new Map();
|
||||||
|
|
||||||
|
setRoleCe(roleCe: RoleCeType) {
|
||||||
|
this.roleId = roleCe.roleId;
|
||||||
|
for(let globalAttr of roleCe.globalAttrs) {
|
||||||
|
let obj = this.getGlobalAttrById(globalAttr.attrId);
|
||||||
|
obj.setByRoleCe(globalAttr);
|
||||||
|
}
|
||||||
|
for(let {hid, lv, attrs} of roleCe.heroAttrs) {
|
||||||
|
this.heroLv.set(hid, lv);
|
||||||
|
for(let cell of attrs) {
|
||||||
|
let obj = this.getHeroAttrByHidAndId(hid, cell.attrId);
|
||||||
|
obj.setByRoleCe(cell);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public getGlobalAttrById(attrId: number) {
|
||||||
|
if(!this.globalAttrs.has(attrId)) {
|
||||||
|
if(ABI_TYPE_MAIN.indexOf(attrId) != -1) {
|
||||||
|
let obj = new GlobalMainAttr(attrId);
|
||||||
|
this.globalAttrs.set(attrId, obj);
|
||||||
|
} else {
|
||||||
|
let obj = new GlobalSubAttr(attrId);
|
||||||
|
this.globalAttrs.set(attrId, obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this.globalAttrs.get(attrId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public getHeroAttrByHidAndId(hid: number, attrId: number) {
|
||||||
|
let key = `${hid}_${attrId}`;
|
||||||
|
if(!this.heroAttrs.has(key)) {
|
||||||
|
if(ABI_TYPE_MAIN.indexOf(attrId) != -1) {
|
||||||
|
let obj = new HeroMainAttr(hid, attrId);
|
||||||
|
this.heroAttrs.set(key, obj);
|
||||||
|
} else {
|
||||||
|
let obj = new HeroSubAttr(hid, attrId);
|
||||||
|
this.heroAttrs.set(key, obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!this.heroAttrsByHid.has(hid)) {
|
||||||
|
this.heroAttrsByHid.set(hid, []);
|
||||||
|
}
|
||||||
|
this.heroAttrsByHid.get(hid).push(key);
|
||||||
|
}
|
||||||
|
return this.heroAttrs.get(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public calHeroCe() {
|
||||||
|
let ces = new Map<number, { id: number, val: number }[]>(); // hid => [{attrId, val}]
|
||||||
|
for(let [hid, keys] of this.heroAttrsByHid) {
|
||||||
|
let lv = this.heroLv.get(hid)||1;
|
||||||
|
for(let key of keys) {
|
||||||
|
let { attrId, base, baseUp, starUp, skillRatio, skill, job } = this.heroAttrs.get(key);
|
||||||
|
let { schoolRatio, title, teraph } = this.getGlobalAttrById(attrId);
|
||||||
|
let val = ( base + lv * ( baseUp + starUp ) + skill + job) * (1 + skillRatio + schoolRatio ) + teraph + title;
|
||||||
|
if(!ces.has(hid)) ces.set(hid, []);
|
||||||
|
ces.get(hid).push({ id: attrId, val });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let result = new Map<number, number>();
|
||||||
|
for(let [hid, arr] of ces) {
|
||||||
|
let obj = new AttributeCal();
|
||||||
|
obj.setByWarJson(arr);
|
||||||
|
result.set(hid, obj.calCe());
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getRoleCeTable() {
|
||||||
|
let globalAttrs: GlobalAttr[] = [];
|
||||||
|
for(let [_, globalAttr] of this.globalAttrs) {
|
||||||
|
globalAttrs.push(globalAttr.getGlobalAttr());
|
||||||
|
}
|
||||||
|
let heroAttrs: HeroAttr[] = [];
|
||||||
|
for(let [hid, keys] of this.heroAttrsByHid) {
|
||||||
|
let lv = this.heroLv.get(hid);
|
||||||
|
let attrs: HeroAttrCell[] = [];
|
||||||
|
for(let key of keys) {
|
||||||
|
let heroAttr = this.heroAttrs.get(key);
|
||||||
|
attrs.push(heroAttr.getHeroAttrCell());
|
||||||
|
}
|
||||||
|
heroAttrs.push({
|
||||||
|
hid, lv, attrs
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
roleId: this.roleId, globalAttrs, heroAttrs
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算函数
|
||||||
|
export class CalCe extends RoleCe {
|
||||||
|
public setInitHero(role: RoleUpdate, heroes: HeroUpdate[]) {
|
||||||
|
for(let { hid, skinId, lv, quality, star, starStage, colorStar, colorStarStage, job, jobStage, } of heroes) {
|
||||||
|
this.setHeroBase(hid, skinId);
|
||||||
|
this.setHeroLv(hid, lv);
|
||||||
|
this.setHeroStar(hid, job, quality, star, starStage, colorStar, colorStarStage);
|
||||||
|
this.setSkill(hid, skinId, star, colorStar);
|
||||||
|
this.setJob(hid, job, jobStage);
|
||||||
|
}
|
||||||
|
this.setTitle(role.title);
|
||||||
|
this.setTeraph(role.teraphs);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 武将基础&成长
|
||||||
|
public setHeroBase(hid: number, skinId: number) {
|
||||||
|
let dicHero = gameData.hero.get(skinId);
|
||||||
|
for(let [attrId, value] of dicHero.baseAbilityArr) {
|
||||||
|
let heroAttr = this.getHeroAttrByHidAndId(hid, attrId);
|
||||||
|
heroAttr.base = value;
|
||||||
|
}
|
||||||
|
for(let [attrId, value] of dicHero.baseAbilityUpArr) {
|
||||||
|
let heroAttr = this.getHeroAttrByHidAndId(hid, attrId);
|
||||||
|
heroAttr.baseUp = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 武将等级
|
||||||
|
public setHeroLv(hid: number, lv: number) {
|
||||||
|
this.heroLv.set(hid, lv);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 星级相关
|
||||||
|
public setHeroStar(hid: number, job: number, quality: number, star: number, starStage: number, colorStar: number, colorStarStage: number) {
|
||||||
|
let dicJob = gameData.job.get(job);
|
||||||
|
let jobClass = dicJob.job_class;
|
||||||
|
const isWake = colorStar > 0; // 是否觉醒,只要激活了觉醒,彩星就会 > 1
|
||||||
|
const dicStar = isWake ? getHeroWakeByQuality(jobClass, quality, colorStar) : getHeroStarByQuality(jobClass, quality, star); // 星级表
|
||||||
|
const dicPreStar = isWake? getHeroWakeByQuality(jobClass, quality, colorStar - 1): getHeroStarByQuality(jobClass, quality, star - 1);
|
||||||
|
let curStage = isWake? colorStarStage: starStage;
|
||||||
|
|
||||||
|
for (let stage = ABI_STAGE.START + 1; stage <= ABI_STAGE.END; stage++) {
|
||||||
|
let attrId = ABI_STAGE_TO_TYPE.get(stage);
|
||||||
|
let value = 0; // 星级成长
|
||||||
|
if(curStage >= stage) {
|
||||||
|
value = dicStar?.ceAttr.get(stage)||0;
|
||||||
|
} else {
|
||||||
|
value = dicPreStar?.ceAttr.get(stage)||0;
|
||||||
|
}
|
||||||
|
let heroAttr = this.getHeroAttrByHidAndId(hid, attrId);
|
||||||
|
heroAttr.starUp = value;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// 武将星级解锁被动技能计算
|
||||||
|
public setSkill(hid: number, skinId: number, _star: number, _colorStar: number) {
|
||||||
|
let seidList = new Map<number, number>(); // type => seid
|
||||||
|
let dicHero = gameData.hero.get(skinId);
|
||||||
|
let { starSeidArr, colorStarSeidArr } = gameData.heroSkill.get(dicHero.skill);
|
||||||
|
for (let { star, value, type } of starSeidArr) {
|
||||||
|
if (_star >= star) seidList.set(type, value);
|
||||||
|
}
|
||||||
|
for (let { star, value, type } of colorStarSeidArr) {
|
||||||
|
if (_colorStar >= star) seidList.set(type, value);
|
||||||
|
}
|
||||||
|
let list: number[] = [];
|
||||||
|
for(let [_type, value] of seidList) list.push(value);
|
||||||
|
let { fixUp, ratioUp } = this.addSeidEffect(list);
|
||||||
|
for(let [attrId, value] of fixUp) {
|
||||||
|
let heroAttr = this.getHeroAttrByHidAndId(hid, attrId);
|
||||||
|
heroAttr.skill = value;
|
||||||
|
}
|
||||||
|
for(let [attrId, value] of ratioUp) {
|
||||||
|
let heroAttr = this.getHeroAttrByHidAndId(hid, attrId);
|
||||||
|
heroAttr.skillRatio = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 职业基础
|
||||||
|
public setJob(hid: number, job: number, jobStage: number) {
|
||||||
|
const dicJob = gameData.job.get(job);
|
||||||
|
for(let i = 1; i <= dicJob.maxStage; i++) {
|
||||||
|
if(jobStage >= i) {
|
||||||
|
let { id, attr } = dicJob.ceAttr.get(i);
|
||||||
|
let heroAttr = this.getHeroAttrByHidAndId(hid, id);
|
||||||
|
heroAttr.job = attr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 爵位
|
||||||
|
public setTitle(title: number) {
|
||||||
|
let dicTitle = gameData.title.get(title)||{ mainAttrValue: new Map(), assiAttrValue: new Map() };
|
||||||
|
for(let [attrId, value] of dicTitle.mainAttrValue) {
|
||||||
|
let globalAttr = this.getGlobalAttrById(attrId);
|
||||||
|
globalAttr.title = value;
|
||||||
|
}
|
||||||
|
for(let [attrId, value] of dicTitle.assiAttrValue) {
|
||||||
|
let globalAttr = this.getGlobalAttrById(attrId);
|
||||||
|
globalAttr.title = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 神像相关
|
||||||
|
public setTeraph(teraphs: Teraph[]) {
|
||||||
|
let teraphOfAttrId = new Map<number, number>();
|
||||||
|
for(let teraph of teraphs) {
|
||||||
|
for(let [attrId, value] of teraph.attr) { // 主属性
|
||||||
|
addToMap(teraphOfAttrId, attrId, value);
|
||||||
|
}
|
||||||
|
let dicTeraph = getTeraph(teraph.id, teraph.grade);
|
||||||
|
for(let [attrId, value] of dicTeraph.assiAttrValue) { // 次属性
|
||||||
|
addToMap(teraphOfAttrId, attrId, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(let [attrId, value] of teraphOfAttrId) {
|
||||||
|
let globalAttr = this.getGlobalAttrById(attrId);
|
||||||
|
globalAttr.teraph = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加技能增加的被动属性
|
||||||
|
private addSeidEffect(seidList: number[]) {
|
||||||
|
let fixUp = new Map<number, number>(), ratioUp = new Map<number, number>();
|
||||||
|
let effectList: DicSe[] = []; // any: dic_zyz_se表内容
|
||||||
|
|
||||||
|
for (let ii = 0; ii < seidList.length; ii += 2) {
|
||||||
|
let seid = seidList[ii];
|
||||||
|
let rand = seidList[ii + 1] || 0;
|
||||||
|
let dicSeid: DicSe | DicRandomEffectPool = gameData.se.get(seid);
|
||||||
|
if (!dicSeid) dicSeid = gameData.randomEffectPool.get(seid);
|
||||||
|
if (dicSeid && dicSeid.id > 0) {
|
||||||
|
this.addSeid(effectList, dicSeid.id, rand, dicSeid.gainValueArr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// console.log('effectList', JSON.stringify(effectList));
|
||||||
|
for (let { type, gainValueArr: [ability, value] } of effectList) {
|
||||||
|
if (type == SEID_TYPE.TYPE101) { // 加值
|
||||||
|
addToMap(fixUp, ability, value);
|
||||||
|
} else if (type == SEID_TYPE.TYPE103) { // 主属性加百分比
|
||||||
|
if(ABI_TYPE_MAIN.includes(ability)) {
|
||||||
|
addToMap(ratioUp, ability, value / 1000);
|
||||||
|
}
|
||||||
|
} else if (type == SEID_TYPE.TYPE104) { // 次级属性加百分比
|
||||||
|
if(!ABI_TYPE_MAIN.includes(ability)) {
|
||||||
|
addToMap(ratioUp, ability, value * 100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return { fixUp, ratioUp };
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取dic_zyz_se内容
|
||||||
|
private addSeid(effectList: (DicSe | DicRandomEffectPool)[], seidId: number, rand: number, seidValue: number[] = []) {
|
||||||
|
let curSeid: DicSe | DicRandomEffectPool = gameData.se.get(seidId);
|
||||||
|
if (!curSeid) curSeid = gameData.randomEffectPool.get(seidId);
|
||||||
|
if (!curSeid) { console.log("seidId not found:" + seidId); return; }
|
||||||
|
if (!seidValue) seidValue = curSeid.gainValueArr;
|
||||||
|
|
||||||
|
if (curSeid.type === SEID_TYPE.TYPE999) {
|
||||||
|
for (let i = 0; i < seidValue.length; i++) {
|
||||||
|
this.addSeid(effectList, seidValue[i], rand);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let seid: DicSe | DicRandomEffectPool = deepCopy(curSeid);
|
||||||
|
if (curSeid.index > 0) {
|
||||||
|
seid.gainValueArr[curSeid.index - 1] = rand;
|
||||||
|
}
|
||||||
|
effectList.push(seid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class GlobalAllAttr {
|
||||||
|
attrId: number;
|
||||||
|
schoolRatio: number = 0;
|
||||||
|
title: number = 0;
|
||||||
|
teraph: number = 0;
|
||||||
|
|
||||||
|
constructor(attrId: number) {
|
||||||
|
this.attrId = attrId;
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract setByRoleCe(data: GlobalAttr): void;
|
||||||
|
abstract getValues(): number[];
|
||||||
|
|
||||||
|
public getGlobalAttr() {
|
||||||
|
return {
|
||||||
|
attrId: this.attrId,
|
||||||
|
values: this.getValues()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class GlobalMainAttr extends GlobalAllAttr {
|
||||||
|
|
||||||
|
public setByRoleCe(globalAttr: GlobalAttr) {
|
||||||
|
for(let i = 0; i < globalAttr.values.length; i++) {
|
||||||
|
let value = globalAttr.values[i];
|
||||||
|
if(value != undefined) {
|
||||||
|
switch(i) {
|
||||||
|
case GLOBAL_ATTR_INDEX.SCHOOL:
|
||||||
|
this.schoolRatio = value; break;
|
||||||
|
case GLOBAL_ATTR_INDEX.TITLE:
|
||||||
|
this.title = value; break;
|
||||||
|
case GLOBAL_ATTR_INDEX.TERAPH:
|
||||||
|
this.teraph = value; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public getValues() {
|
||||||
|
let values: number[] = [];
|
||||||
|
for(let i = GLOBAL_ATTR_INDEX.START; i < GLOBAL_ATTR_INDEX.END; i++) {
|
||||||
|
switch(i) {
|
||||||
|
case GLOBAL_ATTR_INDEX.SCHOOL:
|
||||||
|
values.push(this.schoolRatio); break;
|
||||||
|
case GLOBAL_ATTR_INDEX.TITLE:
|
||||||
|
values.push(this.title); break;
|
||||||
|
case GLOBAL_ATTR_INDEX.TERAPH:
|
||||||
|
values.push(this.teraph); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class GlobalSubAttr extends GlobalAllAttr {
|
||||||
|
|
||||||
|
public setByRoleCe(globalAttr: GlobalAttr) {
|
||||||
|
for(let i = 0; i < globalAttr.values.length; i++) {
|
||||||
|
let value = globalAttr.values[i];
|
||||||
|
if(value != undefined) {
|
||||||
|
switch(i) {
|
||||||
|
case GLOBAL_ATTR_INDEX.SCHOOL:
|
||||||
|
this.schoolRatio = value; break;
|
||||||
|
case GLOBAL_ATTR_INDEX.TITLE:
|
||||||
|
this.title = value; break;
|
||||||
|
case GLOBAL_ATTR_INDEX.TERAPH:
|
||||||
|
this.teraph = value; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public getValues() {
|
||||||
|
let values: number[] = [];
|
||||||
|
for(let i = GLOBAL_ATTR_INDEX.START; i < GLOBAL_ATTR_INDEX.END; i++) {
|
||||||
|
switch(i) {
|
||||||
|
case GLOBAL_ATTR_INDEX.SCHOOL:
|
||||||
|
values.push(this.schoolRatio); break;
|
||||||
|
case GLOBAL_ATTR_INDEX.TITLE:
|
||||||
|
values.push(this.title); break;
|
||||||
|
case GLOBAL_ATTR_INDEX.TERAPH:
|
||||||
|
values.push(this.teraph); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class HeroAllAttr {
|
||||||
|
hid: number;
|
||||||
|
attrId: number;
|
||||||
|
base: number = 0;
|
||||||
|
lv: number = 0;
|
||||||
|
baseUp: number = 0;
|
||||||
|
starUp: number = 0;
|
||||||
|
skillRatio: number = 0;
|
||||||
|
skill: number = 0;
|
||||||
|
job: number = 0;
|
||||||
|
|
||||||
|
constructor(hid: number, attrId: number, ) {
|
||||||
|
this.hid = hid;
|
||||||
|
this.attrId = attrId;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract setByRoleCe(data: GlobalAttr): void;
|
||||||
|
abstract getValues(): number[];
|
||||||
|
|
||||||
|
public getHeroAttrCell() {
|
||||||
|
return {
|
||||||
|
attrId: this.attrId,
|
||||||
|
values: this.getValues()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class HeroMainAttr extends HeroAllAttr {
|
||||||
|
public setByRoleCe(heroAttr: HeroAttrCell) {
|
||||||
|
for(let i = 0; i < heroAttr.values.length; i++) {
|
||||||
|
let value = heroAttr.values[i];
|
||||||
|
if(value != undefined) {
|
||||||
|
switch(i) {
|
||||||
|
case HERO_ATTR_INDEX.BASE:
|
||||||
|
this.base = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public getValues() {
|
||||||
|
let values: number[] = [];
|
||||||
|
for(let i = HERO_ATTR_INDEX.START; i < HERO_ATTR_INDEX.END; i++) {
|
||||||
|
switch(i) {
|
||||||
|
case HERO_ATTR_INDEX.BASE:
|
||||||
|
values.push(this.base); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class HeroSubAttr extends HeroAllAttr {
|
||||||
|
public setByRoleCe(heroAttr: HeroAttrCell) {
|
||||||
|
for(let i = 0; i < heroAttr.values.length; i++) {
|
||||||
|
let value = heroAttr.values[i];
|
||||||
|
if(value != undefined) {
|
||||||
|
switch(i) {
|
||||||
|
case HERO_ATTR_INDEX.BASE:
|
||||||
|
this.base = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public getValues() {
|
||||||
|
let values: number[] = [];
|
||||||
|
for(let i = HERO_ATTR_INDEX.START; i < HERO_ATTR_INDEX.END; i++) {
|
||||||
|
switch(i) {
|
||||||
|
case HERO_ATTR_INDEX.BASE:
|
||||||
|
values.push(this.base); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum GLOBAL_ATTR_INDEX {
|
||||||
|
START,
|
||||||
|
SCHOOL = 0,
|
||||||
|
TITLE = 1,
|
||||||
|
TERAPH = 2,
|
||||||
|
END
|
||||||
|
}
|
||||||
|
|
||||||
|
enum HERO_ATTR_INDEX {
|
||||||
|
START,
|
||||||
|
BASE = 0, // 角色基础属性(dic_zyz_hero的hp)
|
||||||
|
BASE_UP = 1,
|
||||||
|
END
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import { FIGURE_UNLOCK_CONDITION, ITEM_CHANGE_REASON, REDIS_KEY, STATUS, TASK_TYPE, HERO_SYSTEM_TYPE } from "../../consts";
|
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 { SkinModel } from "../../db/Skin";
|
||||||
import { HeroModel, HeroSkin, HeroType, HeroUpdate } from "../../db/Hero";
|
import { HeroModel, HeroSkin, HeroType, HeroUpdate } from "../../db/Hero";
|
||||||
import { RoleModel, RoleType, RoleUpdate } from "../../db/Role";
|
import { RoleModel, RoleType, RoleUpdate } from "../../db/Role";
|
||||||
@@ -8,7 +8,7 @@ import { TaskListReturn } from "../../domain/roleField/task";
|
|||||||
import { GuildModel, GuildType } from "../../db/Guild";
|
import { GuildModel, GuildType } from "../../db/Guild";
|
||||||
import { PvpDefenseModel } from "../../db/PvpDefense";
|
import { PvpDefenseModel } from "../../db/PvpDefense";
|
||||||
import { pick } from "underscore";
|
import { pick } from "underscore";
|
||||||
import { calculatetopLineup } from "../../pubUtils/playerCe";
|
import { calculatetopLineup } from "../../pubUtils/util";
|
||||||
import { nowSeconds } from "../../pubUtils/timeUtil";
|
import { nowSeconds } from "../../pubUtils/timeUtil";
|
||||||
import { saveCeChangeLog } from "../../pubUtils/logUtil";
|
import { saveCeChangeLog } from "../../pubUtils/logUtil";
|
||||||
import { getRandSingleEelm, reduceCe, resResult } from "../../pubUtils/util";
|
import { getRandSingleEelm, reduceCe, resResult } from "../../pubUtils/util";
|
||||||
@@ -20,18 +20,28 @@ import { checkTaskInCreateHero } from "../task/taskService";
|
|||||||
import { ItemInter, RewardInter } from "../../pubUtils/interface";
|
import { ItemInter, RewardInter } from "../../pubUtils/interface";
|
||||||
import { transPiece } from "./util";
|
import { transPiece } from "./util";
|
||||||
import { getInitHeroById } from "../roleService";
|
import { getInitHeroById } from "../roleService";
|
||||||
import { addItems, combineFigureInfo, unlockFigureWithoutSave } from "./rewardService";
|
import { addItems, combineFigureInfo, unlockFigure, unlockFigureWithoutSave } from "./rewardService";
|
||||||
|
import { gameData } from "../../pubUtils/data";
|
||||||
|
import { CalCe } from "./calCe";
|
||||||
|
import { RoleCeUpdate } from "../../db/RoleCe";
|
||||||
|
|
||||||
export class UpdateHeroes {
|
export class CreateHeroes {
|
||||||
roleId: string;
|
private roleId: string;
|
||||||
roleName: string;
|
private roleName: string;
|
||||||
serverId: number;
|
private serverId: number;
|
||||||
incHeroNum: number = 0;
|
private incHeroNum: number = 0;
|
||||||
incRoleCe: number = 0;
|
private incRoleCe: number = 0;
|
||||||
pushHeroes: {hid: number, incHeroCe: number, ce: number, hero: HeroUpdate}[] = [];
|
private role: RoleType;
|
||||||
roleUpdate: RoleUpdate;
|
private guild: GuildType;
|
||||||
role: RoleType;
|
|
||||||
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) {
|
constructor(roleId: string, roleName: string, serverId: number) {
|
||||||
this.roleId = roleId;
|
this.roleId = roleId;
|
||||||
@@ -46,43 +56,66 @@ export class UpdateHeroes {
|
|||||||
public async getRole() {
|
public async getRole() {
|
||||||
if(!this.role) {
|
if(!this.role) {
|
||||||
this.role = await RoleModel.findByRoleId(this.roleId);
|
this.role = await RoleModel.findByRoleId(this.roleId);
|
||||||
|
this.topLineup = this.role.topLineup;
|
||||||
|
this.topLineupCe = this.role.topLineupCe;
|
||||||
}
|
}
|
||||||
return this.role;
|
return this.role;
|
||||||
}
|
}
|
||||||
|
|
||||||
public addRoleUpdateParam(param: RoleUpdate) {
|
public async createHeroes(hids: number[]) {
|
||||||
this.roleUpdate = {...this.roleUpdate, ...param};
|
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();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async updateDbCe(isCreate: boolean, heroInfo: HeroUpdate, originCe = 0) {
|
private async calCe() {
|
||||||
let role = await this.getRole();
|
let role = await this.getRole();
|
||||||
if(isCreate) this.incHeroNum ++;
|
let calCe = new CalCe();
|
||||||
if(heroInfo != originCe) this.incRoleCe += heroInfo.ce - originCe;
|
calCe.setInitHero(role, this.heroes); // 设置武将初始信息
|
||||||
this.addRoleUpdateParam(await calculatetopLineup(role, heroInfo.hid, heroInfo.ce, heroInfo._id ));
|
let ces = calCe.calHeroCe(); // 战力
|
||||||
this.pushHeroes.push({ hid: heroInfo.hid, incHeroCe: heroInfo.ce - originCe, ce: heroInfo.ce, hero: heroInfo });
|
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();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更新战力相关的各个表
|
// 更新战力相关的各个表
|
||||||
public async saveCeToDb() {
|
private async saveCeToDb() {
|
||||||
let role = await this.getRole();
|
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表
|
||||||
this.role = await RoleModel.updateRoleInfo(this.roleId, {
|
role = await RoleModel.incRoleInfo(this.roleId, { heroNum: this.incHeroNum, ce: this.incRoleCe }, { heroNumUpdatedAt: nowSeconds(), });
|
||||||
heroNum: this.incHeroNum + role.heroNum, ce: this.incRoleCe + role.ce, heroNumUpdatedAt: nowSeconds(), ...this.roleUpdate
|
this.setRole(role);
|
||||||
});
|
// 更新皮肤表
|
||||||
|
await SkinModel.insertSkins(this.roleId, this.roleName, this.skins)
|
||||||
// 更新guild表
|
// 更新guild表
|
||||||
if(role.hasGuild) {
|
if(role.hasGuild) {
|
||||||
this.guild = await GuildModel.updateCe(this.roleId, this.incRoleCe, true); // 公会更新战力
|
this.guild = await GuildModel.updateCe(this.roleId, this.incRoleCe, true); // 公会更新战力
|
||||||
}
|
}
|
||||||
for(let { hid, incHeroCe } of this.pushHeroes) {
|
for(let { hid, ce } of this.resultHeroes) {
|
||||||
await PvpDefenseModel.updateCe(this.roleId, hid, incHeroCe); // 更新pvp防守阵战力
|
await PvpDefenseModel.updateCe(this.roleId, hid, ce); // 更新pvp防守阵战力
|
||||||
}
|
}
|
||||||
saveCeChangeLog(this.role, this.incRoleCe, this.role.ce, HERO_SYSTEM_TYPE.INIT, this.pushHeroes.map(cur => cur.hid));
|
saveCeChangeLog(role, this.incRoleCe, role.ce, HERO_SYSTEM_TYPE.INIT, this.resultHeroes.map(cur => cur.hid));
|
||||||
}
|
}
|
||||||
|
|
||||||
public async updateRedisRank() {
|
public async updateRedisRank() {
|
||||||
let role = await this.getRole();
|
let { serverId, roleId, resultHeroes, role } = this;
|
||||||
let { serverId, roleId, pushHeroes } = this;
|
|
||||||
// 更新军团信息
|
// 更新军团信息
|
||||||
if(this.guild) {
|
if(this.guild) {
|
||||||
let r = new Rank(REDIS_KEY.GUILD_INFO, { guildCode: this.guild.code });
|
let r = new Rank(REDIS_KEY.GUILD_INFO, { guildCode: this.guild.code });
|
||||||
@@ -99,12 +132,12 @@ export class UpdateHeroes {
|
|||||||
await r.setRankWithRoleInfo(roleId, reduceCe(role.topLineupCe), 0, role);
|
await r.setRankWithRoleInfo(roleId, reduceCe(role.topLineupCe), 0, role);
|
||||||
|
|
||||||
// 最强武将
|
// 最强武将
|
||||||
for(let { hid, ce, hero } of pushHeroes) {
|
for(let hero of resultHeroes) {
|
||||||
let r2 = new Rank(REDIS_KEY.TOP_HERO_RANK, { serverId });
|
let r2 = new Rank(REDIS_KEY.TOP_HERO_RANK, { serverId });
|
||||||
await r2.setRankWithHeroInfo(roleId, hid, reduceCe(ce), 0, hero);
|
await r2.setRankWithHeroInfo(roleId, hero.hid, hero.ce, 0, hero);
|
||||||
|
|
||||||
let r4 = new Rank(REDIS_KEY.HERO_RANK, { serverId, hid });
|
let r4 = new Rank(REDIS_KEY.HERO_RANK, { serverId, hid: hero.hid });
|
||||||
await r4.setRankWithHeroInfo(roleId, hid, reduceCe(ce), 0, hero);
|
await r4.setRankWithHeroInfo(roleId, hero.hid, hero.ce, 0, hero);
|
||||||
}
|
}
|
||||||
// 总战力
|
// 总战力
|
||||||
let r3 = new Rank(REDIS_KEY.SUM_CE_RANK, { serverId });
|
let r3 = new Rank(REDIS_KEY.SUM_CE_RANK, { serverId });
|
||||||
@@ -115,90 +148,26 @@ export class UpdateHeroes {
|
|||||||
await r5.generParamAndSet(REDIS_KEY.TOP_LINEUP_INFO, { roleId }, { role });
|
await r5.generParamAndSet(REDIS_KEY.TOP_LINEUP_INFO, { roleId }, { role });
|
||||||
}
|
}
|
||||||
|
|
||||||
public async pushMessage(pinus: any, sid: string) {
|
|
||||||
let role = await this.getRole();
|
|
||||||
let uids = [{ uid: this.roleId, sid }];
|
|
||||||
pinus.app.get('channelService').pushMessageByUids('onPlayerCeUpdate', resResult(STATUS.SUCCESS, { ce: reduceCe(role.ce) , heros: this.pushHeroes.map(cur => { return {...cur, ce: reduceCe(cur.ce), incHeroCe: reduceCe(cur.incHeroCe) }}), topLineupCe: reduceCe(role.topLineupCe) }), uids);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
export class CreateHeroes extends UpdateHeroes {
|
|
||||||
private resultHeroes: HeroType[] = [];
|
|
||||||
private heroNum = 0;
|
|
||||||
// 推送信息
|
|
||||||
private figureInfos: { heads: Figure[], frames: Figure[], spines: Figure[] }[] = [];
|
|
||||||
private skinPushMessages: { heros: {skins: HeroSkin[], hid: number}[], skins: {id: number, hid: number, inc: number, reason: number }[]} = { heros: [], skins: [] };
|
|
||||||
|
|
||||||
private async getSkinsOfThisHero(hid: number, initSkinInfo: SkinUpdate, isInit: boolean) {
|
|
||||||
let allSkins = isInit? []: await SkinModel.findbyRoleAndHid(this.roleId, hid);
|
|
||||||
let skin = await SkinModel.insertSkins(this.roleId, this.roleName, [initSkinInfo]);
|
|
||||||
let skinInfos = skin.map(cur => ({ id: cur.id, hid, inc: 1, reason: ITEM_CHANGE_REASON.GET_HERO_UNLOCK_SKIN}))
|
|
||||||
this.skinPushMessages.skins.push(...skinInfos);
|
|
||||||
if(skin) allSkins.push(...skin);
|
|
||||||
let skins: HeroSkin[] = [];
|
|
||||||
for(let skin of allSkins) {
|
|
||||||
skins.push(new HeroSkin(skin.id, skin.skinId, skin._id, skin.id == initSkinInfo.id));
|
|
||||||
}
|
|
||||||
return skins
|
|
||||||
}
|
|
||||||
|
|
||||||
// game-server里面创建武将
|
|
||||||
public async createWithHeroInfo(infos: Map<number, { heroInfo: HeroUpdate, skinInfo: SkinUpdate }>) {
|
|
||||||
let role = await this.getRole();
|
|
||||||
// 数据处理
|
|
||||||
let conditions = new Array<{ type: number, paramHid?: number, paramFavourLv?: number, paramSkinId?: number }>(); // 解锁头像条件
|
|
||||||
let initHeroInfos: HeroUpdate[] = [];
|
|
||||||
for (let [ hid, { heroInfo, skinInfo }] of infos) {
|
|
||||||
conditions.push({ type: FIGURE_UNLOCK_CONDITION.GET_HERO, paramHid: heroInfo.hid });
|
|
||||||
this.updateDbCe(true, heroInfo);
|
|
||||||
// 皮肤使用初始加载进内存的数据
|
|
||||||
let skins = await this.getSkinsOfThisHero(hid, { ...skinInfo, _id: new SkinModel()._id }, false);
|
|
||||||
let newAttr = new AttributeCal();
|
|
||||||
newAttr.setLv(heroInfo.lv);
|
|
||||||
newAttr.setByDbData(role.attr, heroInfo.attr);
|
|
||||||
let heroCe = newAttr.calCe(); // 计算最终战力
|
|
||||||
initHeroInfos.push({ ...heroInfo, skins, _id: new HeroModel()._id, ce: heroCe });
|
|
||||||
this.heroNum ++;
|
|
||||||
}
|
|
||||||
// 武将使用初始加载数据插入
|
|
||||||
this.resultHeroes = await HeroModel.insertHeroes(this.roleId, this.roleName, this.serverId, initHeroInfos);
|
|
||||||
let heroSkins = this.resultHeroes.map(cur => { return pick(cur, ['hid', 'skins']) });
|
|
||||||
|
|
||||||
this.skinPushMessages.heros.push(...heroSkins);
|
|
||||||
// 头像解锁
|
|
||||||
let { figureInfo, frames, heads, spines } = unlockFigureWithoutSave(conditions, role);
|
|
||||||
this.figureInfos.push(figureInfo);
|
|
||||||
this.addRoleUpdateParam({ frames, heads, spines });
|
|
||||||
// 更新战力
|
|
||||||
await this.saveCeToDb();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 创建初始账号时候的初始
|
|
||||||
public async createWithInitInfo(infos: Map<number, { heroInfo: HeroUpdate, skinInfo: SkinUpdate }>, figureInfo: { heads: Figure[], frames: Figure[], spines: Figure[] }) {
|
|
||||||
this.figureInfos.push(figureInfo);
|
|
||||||
let heroeInfos: HeroUpdate[] = [];
|
|
||||||
for (let [ hid, { heroInfo, skinInfo }] of infos) {
|
|
||||||
this.updateDbCe(true, heroInfo);
|
|
||||||
let model = new SkinModel();
|
|
||||||
let skins = await this.getSkinsOfThisHero(hid, { ...skinInfo, _id: model._id }, true);
|
|
||||||
heroeInfos.push({ ...heroInfo, skins, _id: new HeroModel()._id});
|
|
||||||
this.heroNum ++;
|
|
||||||
}
|
|
||||||
this.resultHeroes = await HeroModel.insertHeroes(this.roleId, this.roleName, this.serverId, heroeInfos);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async pushMessage(sid: string) {
|
public async pushMessage(sid: string) {
|
||||||
let role = await this.getRole();
|
let role = await this.getRole();
|
||||||
let uids = [{ uid: this.roleId, sid }];
|
let uids = [{ uid: this.roleId, sid }];
|
||||||
pinus.app.get('channelService').pushMessageByUids('onPlayerCeUpdate', resResult(STATUS.SUCCESS, { ce: reduceCe(role.ce) , heros: this.pushHeroes.map(cur => { return {...cur, ce: reduceCe(cur.ce), incHeroCe: reduceCe(cur.incHeroCe) }}), topLineupCe: reduceCe(role.topLineupCe) }), uids);
|
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);
|
||||||
let figureInfo = combineFigureInfo(this.figureInfos);
|
|
||||||
if (!!figureInfo && (figureInfo.heads.length > 0 || figureInfo.frames.length > 0 || figureInfo.spines.length > 0)) {
|
pinus.app.get('channelService').pushMessageByUids('onHeroSkinChange', resResult(STATUS.SUCCESS, this.getSkinPushMsg()), uids);
|
||||||
pinus.app.get('channelService').pushMessageByUids('onHeadChange', resResult(STATUS.SUCCESS, { ...figureInfo }), uids);
|
|
||||||
}
|
|
||||||
pinus.app.get('channelService').pushMessageByUids('onHeroSkinChange', resResult(STATUS.SUCCESS, this.skinPushMessages), uids);
|
|
||||||
pinus.app.get('channelService').pushMessageByUids('onHeroUpdate', resResult(STATUS.SUCCESS, { heroes: this.getResultHeroes() }), uids);
|
pinus.app.get('channelService').pushMessageByUids('onHeroUpdate', resResult(STATUS.SUCCESS, { heroes: this.getResultHeroes() }), uids);
|
||||||
checkTaskInCreateHero(this.serverId, this.roleId, sid, this.heroNum, this.resultHeroes)
|
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() {
|
public getResultHeroes() {
|
||||||
@@ -225,25 +194,14 @@ export class CreateHeroes extends UpdateHeroes {
|
|||||||
let hids = heroInfo.map(cur => cur.hid);
|
let hids = heroInfo.map(cur => cur.hid);
|
||||||
let userHeroesMap = await HeroModel.findMapByHidRange(hids, roleId);
|
let userHeroesMap = await HeroModel.findMapByHidRange(hids, roleId);
|
||||||
|
|
||||||
let infos: Map<number, { heroInfo: HeroUpdate, skinInfo: SkinUpdate }> = new Map(), pieces: ItemInter[] = [];
|
let createHids: number[] = [], pieces: ItemInter[] = [];
|
||||||
for (let h of heroInfo) {
|
for (let h of heroInfo) {
|
||||||
let heroCount = h.count || 1;
|
let heroCount = h.count || 1;
|
||||||
if (userHeroesMap.has(h.hid)) {
|
if (userHeroesMap.has(h.hid)) {
|
||||||
let { pieceId, count } = transPiece(h.hid);
|
let { pieceId, count } = transPiece(h.hid);
|
||||||
pieces.push({ id: pieceId, count: count * heroCount });
|
pieces.push({ id: pieceId, count: count * heroCount });
|
||||||
} else {
|
} else {
|
||||||
let initInfo: { heroInfo: HeroUpdate, skinInfo: SkinUpdate };
|
createHids.push(h.hid);
|
||||||
if(pinus.app.getServerType() == 'role') {
|
|
||||||
initInfo = getInitHeroById(h.hid);
|
|
||||||
} else {
|
|
||||||
let roleServers = pinus.app.getServersByType('role');
|
|
||||||
let server = getRandSingleEelm(roleServers);
|
|
||||||
initInfo = await pinus.app.rpc.role.roleRemote.getInitHeroById.toServer(server.id, h.hid);
|
|
||||||
}
|
|
||||||
|
|
||||||
initInfo.heroInfo = { ...initInfo.heroInfo, ...h };
|
|
||||||
|
|
||||||
infos.set(h.hid, initInfo);
|
|
||||||
userHeroesMap.set(h.hid, null);
|
userHeroesMap.set(h.hid, null);
|
||||||
if (heroCount > 1) {
|
if (heroCount > 1) {
|
||||||
let { pieceId, count } = transPiece(h.hid);
|
let { pieceId, count } = transPiece(h.hid);
|
||||||
@@ -253,9 +211,9 @@ export class CreateHeroes extends UpdateHeroes {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let resultHeroes: HeroType[] = [], resultItems: RewardInter[] = [], heroes: HeroShowParam[] = [];
|
let resultHeroes: HeroType[] = [], resultItems: RewardInter[] = [], heroes: HeroShowParam[] = [];
|
||||||
if (infos.size > 0) {
|
if (createHids.length > 0) {
|
||||||
let createHero = new CreateHeroes(roleId, roleName, serverId);
|
let createHero = new CreateHeroes(roleId, roleName, serverId);
|
||||||
await createHero.createWithHeroInfo(infos);
|
await createHero.createHeroes(createHids);
|
||||||
await createHero.pushMessage(sid);
|
await createHero.pushMessage(sid);
|
||||||
await createHero.updateRedisRank();
|
await createHero.updateRedisRank();
|
||||||
heroes = createHero.getShowHeroes();
|
heroes = createHero.getShowHeroes();
|
||||||
|
|||||||
@@ -1,61 +0,0 @@
|
|||||||
import { DEFAULT_HEROES, DEFAULT_HERO_LV, FIGURE_UNLOCK_CONDITION, HERO_SYSTEM_TYPE, LINEUP_NUM } from "../../consts";
|
|
||||||
import { HeroModel, HeroSkin, HeroUpdate } from "../../db/Hero";
|
|
||||||
import { RoleModel, RoleUpdate } from "../../db/Role";
|
|
||||||
import { SkinModel, SkinUpdate } from "../../db/Skin";
|
|
||||||
import { TopHero } from "../../domain/dbGeneral";
|
|
||||||
import { CalHeroCe, CalRoleCe } from "../../domain/roleField/calCe";
|
|
||||||
import { gameData, getHeroExpByLv } from "../../pubUtils/data";
|
|
||||||
import { unlockFigureWithoutSave } from "./rewardService";
|
|
||||||
|
|
||||||
// 储存在内存中的初始数据
|
|
||||||
export function getInitRoleInfo() {
|
|
||||||
let topLineup: TopHero[] = [], topLineupCe = 0, allCe = 0,
|
|
||||||
heroes: HeroUpdate[] = [], initHeroes: HeroUpdate[] = [], initSkins: SkinUpdate[] = [], heroNum = 0,
|
|
||||||
conditions: {type: FIGURE_UNLOCK_CONDITION, paramHid: number }[] = [];
|
|
||||||
let role = new RoleModel();
|
|
||||||
let calRoleCe = new CalRoleCe(role);
|
|
||||||
let roleAttr = calRoleCe.cal(HERO_SYSTEM_TYPE.INIT);
|
|
||||||
|
|
||||||
for(let { actorId: hid } of gameData.recruit) {
|
|
||||||
let { quality, initialStars: star, jobid: job, name: hName, initialSkin } = gameData.hero.get(hid);
|
|
||||||
// 皮肤
|
|
||||||
let skin = new SkinModel();
|
|
||||||
let dicFashion = gameData.fashion.get(initialSkin);
|
|
||||||
if(!dicFashion) {
|
|
||||||
console.log(`not found skin: ${initialSkin} of ${hid}`);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
let skinInfo = { ...skin.toJSON(), id: initialSkin, hid, skinName: dicFashion.name, skinId: dicFashion.heroId };
|
|
||||||
initSkins.push(skinInfo);
|
|
||||||
// 武将
|
|
||||||
let hero = new HeroModel();
|
|
||||||
let heroInfo = {...hero.toJSON(), hid, star, quality, hName, job, skins: [new HeroSkin(initialSkin, skinInfo.skinId, skinInfo._id, true)], skinId: skinInfo.skinId, lv: DEFAULT_HERO_LV, exp: getHeroExpByLv(DEFAULT_HERO_LV - 1) || 0 };
|
|
||||||
let calHeroCe = new CalHeroCe(hid, heroInfo);
|
|
||||||
let heroAttr = calHeroCe.cal(HERO_SYSTEM_TYPE.INIT);
|
|
||||||
let ce = calHeroCe.getCalculatedCe(roleAttr);
|
|
||||||
heroes.push({ ...heroInfo, attr: heroAttr, ce, historyCe: ce });
|
|
||||||
// 更新role表
|
|
||||||
if(DEFAULT_HEROES.includes(hid)) {
|
|
||||||
// 头像
|
|
||||||
conditions.push({ type: FIGURE_UNLOCK_CONDITION.GET_HERO, paramHid: hid });
|
|
||||||
allCe += ce;
|
|
||||||
heroNum++;
|
|
||||||
initHeroes.push({ ...heroInfo, attr: heroAttr, ce, historyCe: ce });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let { figureInfo, heads, frames, spines } = unlockFigureWithoutSave(conditions, role);
|
|
||||||
// 最强阵容
|
|
||||||
initHeroes.sort((a, b) => { return b.ce - a.ce });
|
|
||||||
for(let i = 0; i < LINEUP_NUM; i++) {
|
|
||||||
if(initHeroes[i]) {
|
|
||||||
let { hid, ce, _id } = initHeroes[i];
|
|
||||||
topLineup.push({ hid, ce, hero: _id });
|
|
||||||
topLineupCe += ce;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let initRole: RoleUpdate = { topLineupCe, topLineup, attr: roleAttr, ce: allCe, heroNum, heroNumUpdatedAt: Date.now(), heads, frames, spines };
|
|
||||||
return {
|
|
||||||
role: initRole, heroes, skins: initSkins, figureInfo
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -367,7 +367,7 @@ export async function addSkin(roleId: string, roleName: string, sid: string, ski
|
|||||||
if (hero) { // 有武将的,将皮肤链接到武将上
|
if (hero) { // 有武将的,将皮肤链接到武将上
|
||||||
let curSkin = hero.skins.find(cur => cur.id == skinId);
|
let curSkin = hero.skins.find(cur => cur.id == skinId);
|
||||||
if (!curSkin) {
|
if (!curSkin) {
|
||||||
hero.skins.push(new HeroSkin(skin.id, skin.skinId, skin._id, enable ));
|
hero.skins.push(new HeroSkin(skin, enable));
|
||||||
await HeroModel.updateHeroInfo(roleId, hero.hid, hero);
|
await HeroModel.updateHeroInfo(roleId, hero.hid, hero);
|
||||||
}
|
}
|
||||||
return hero;
|
return hero;
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
import { ChannelUser } from './../domain/ChannelUser';
|
import { ChannelUser } from './../domain/ChannelUser';
|
||||||
import { Channel, pinus } from 'pinus';
|
import { Channel, pinus } from 'pinus';
|
||||||
import { getRandValueByMinMax, getRandEelm, decodeIdCntArrayStr } from '../pubUtils/util';
|
import { getRandValueByMinMax, getRandEelm, decodeIdCntArrayStr } from '../pubUtils/util';
|
||||||
import { DEFAULT_HEROES, ROLE_SELECT, TALENT_RELATION_TYPE, TERAPH_RANDOM } from "../consts";
|
import { DEFAULT_HEROES, LINEUP_NUM, ROLE_SELECT, TALENT_RELATION_TYPE, TERAPH_RANDOM } from "../consts";
|
||||||
import { DicTeraph } from '../pubUtils/dictionary/DicTeraph';
|
import { DicTeraph } from '../pubUtils/dictionary/DicTeraph';
|
||||||
import { Teraph, RoleModel, RoleType, RoleUpdate } from '../db/Role';
|
import { Teraph, RoleModel, RoleType, RoleUpdate } from '../db/Role';
|
||||||
import { SCHOOL } from '../pubUtils/dicParam';
|
import { SCHOOL } from '../pubUtils/dicParam';
|
||||||
import { gameData, getHeroInitTalent } from '../pubUtils/data';
|
import { gameData, getHeroInitTalent } from '../pubUtils/data';
|
||||||
import { SchoolModel } from '../db/School';
|
import { SchoolModel } from '../db/School';
|
||||||
import { SclResultInter, SclPosInter, RewardInter, ItemInter } from '../pubUtils/interface';
|
import { SclResultInter, SclPosInter, RewardInter, ItemInter } from '../pubUtils/interface';
|
||||||
import { HeroSkin, HeroUpdate, Talent } from '../db/Hero';
|
import { HeroModel, HeroSkin, HeroUpdate, Talent } from '../db/Hero';
|
||||||
import { SkinUpdate } from '../db/Skin';
|
import { SkinUpdate } from '../db/Skin';
|
||||||
import { Figure } from '../domain/dbGeneral';
|
import { Figure } from '../domain/dbGeneral';
|
||||||
import { pick } from 'underscore';
|
import { pick } from 'underscore';
|
||||||
@@ -251,4 +251,4 @@ export function initSkinTalent(skins: HeroSkin[], isAll = false) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return newSkins
|
return newSkins
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,12 +2,12 @@ import BaseModel from './BaseModel';
|
|||||||
import { index, getModelForClass, prop, Ref, mongoose, DocumentType } from '@typegoose/typegoose';
|
import { index, getModelForClass, prop, Ref, mongoose, DocumentType } from '@typegoose/typegoose';
|
||||||
// import Equip, { } from './Equip';
|
// import Equip, { } from './Equip';
|
||||||
import { CounterModel } from './Counter';
|
import { CounterModel } from './Counter';
|
||||||
import { COUNTER, HERO_CE_RATIO } from '../consts';
|
import { COUNTER, DEFAULT_HERO_LV, HERO_CE_RATIO } from '../consts';
|
||||||
import { reduceCe } from '../pubUtils/util';
|
import { reduceCe } from '../pubUtils/util';
|
||||||
import Skin from './Skin';
|
import Skin, { SkinUpdate } from './Skin';
|
||||||
import { SearchHeroParam } from '../domain/backEndField/search';
|
import { SearchHeroParam } from '../domain/backEndField/search';
|
||||||
import { Reward } from '../domain/battleField/pvp';
|
import { Reward } from '../domain/battleField/pvp';
|
||||||
import { getHeroInitTalent } from '../pubUtils/data';
|
import { gameData, getHeroExpByLv, getHeroInitTalent } from '../pubUtils/data';
|
||||||
|
|
||||||
type CeAttrUpdate = Partial<CeAttrData>;
|
type CeAttrUpdate = Partial<CeAttrData>;
|
||||||
export class CeAttrData {
|
export class CeAttrData {
|
||||||
@@ -88,12 +88,12 @@ export class HeroSkin {
|
|||||||
@prop({ required: true })
|
@prop({ required: true })
|
||||||
usedTalentPoint: number; // 已使用的天赋点数
|
usedTalentPoint: number; // 已使用的天赋点数
|
||||||
|
|
||||||
constructor(id: number, skinId: number, skin: string, enable: boolean) {
|
constructor(skin: SkinUpdate, enable = true) {
|
||||||
this.id = id;
|
this.id = skin.id;
|
||||||
this.skinId = skinId;
|
this.skinId = skin.skinId;
|
||||||
this.skin = skin;
|
this.skin = skin._id;
|
||||||
this.enable = enable;
|
this.enable = enable;
|
||||||
this.talent = getHeroInitTalent(skinId);
|
this.talent = getHeroInitTalent(skin.skinId);
|
||||||
this.usedTalentPoint = 0;
|
this.usedTalentPoint = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -274,16 +274,18 @@ export default class Hero extends BaseModel {
|
|||||||
return hero;
|
return hero;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static getInitInfo(heroInfo: HeroUpdate = {}): HeroUpdate {
|
public static getInitInfo(hid: number, heroInfo: HeroUpdate = {}): HeroUpdate {
|
||||||
|
let dicHero = gameData.hero.get(hid)
|
||||||
|
let { quality, initialStars: star, jobid: job, name: hName } = dicHero;
|
||||||
const doc = new HeroModel();
|
const doc = new HeroModel();
|
||||||
const update = { ...doc.toJSON(), ...heroInfo};
|
const update = { ...doc.toJSON(), hid, skinId: hid, hName, star, quality, job, lv: DEFAULT_HERO_LV, exp: getHeroExpByLv(DEFAULT_HERO_LV - 1) || 0, ...heroInfo};
|
||||||
delete update._id;
|
delete update._id;
|
||||||
return update
|
return update
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async createHero(heroInfo: HeroUpdate, lean = true) {
|
public static async createHero(heroInfo: HeroUpdate, lean = true) {
|
||||||
const seqId = await CounterModel.getNewCounter(COUNTER.HID) || -1;
|
const seqId = await CounterModel.getNewCounter(COUNTER.HID) || -1;
|
||||||
const update = this.getInitInfo({ ...heroInfo, seqId });
|
const update = this.getInitInfo(heroInfo.hid, { ...heroInfo, seqId });
|
||||||
const hero: HeroType = await HeroModel.findOneAndUpdate({ roleId: heroInfo.roleId, hid: heroInfo.hid }, update, { upsert: true, new: true }).lean(lean);
|
const hero: HeroType = await HeroModel.findOneAndUpdate({ roleId: heroInfo.roleId, hid: heroInfo.hid }, update, { upsert: true, new: true }).lean(lean);
|
||||||
return hero;
|
return hero;
|
||||||
}
|
}
|
||||||
|
|||||||
98
shared/db/RoleCe.ts
Normal file
98
shared/db/RoleCe.ts
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
import BaseModel from './BaseModel';
|
||||||
|
import { index, getModelForClass, prop, DocumentType } from '@typegoose/typegoose';
|
||||||
|
|
||||||
|
// 全局加成
|
||||||
|
export class GlobalAttr {
|
||||||
|
@prop({ required: true })
|
||||||
|
attrId: number; // 属性id
|
||||||
|
@prop({ required: true })
|
||||||
|
values: number[]; // 战力公式中的全局加成的数据,查表后的结果
|
||||||
|
}
|
||||||
|
|
||||||
|
// 单武将加成
|
||||||
|
export class HeroAttr {
|
||||||
|
@prop({ required: true })
|
||||||
|
hid: number; // 武将id
|
||||||
|
@prop({ required: true })
|
||||||
|
lv: number;
|
||||||
|
@prop({ required: true, type: () => HeroAttrCell, _id: false })
|
||||||
|
attrs: HeroAttrCell[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export class HeroAttrCell {
|
||||||
|
@prop({ required: true })
|
||||||
|
attrId: number; // 属性id
|
||||||
|
@prop({ required: true })
|
||||||
|
values: number[]; // 战力公式中的武将加成的数据,查表后的结果
|
||||||
|
}
|
||||||
|
|
||||||
|
// 装备加成
|
||||||
|
class EquipAttr {
|
||||||
|
@prop({ required: true })
|
||||||
|
hid: number; // 武将id
|
||||||
|
@prop({ required: true })
|
||||||
|
eplaceId: number; // 装备位置
|
||||||
|
@prop({ required: true })
|
||||||
|
attrId: number; // 属性id
|
||||||
|
@prop({ required: true })
|
||||||
|
values: number[]; // 战力公式中的武将加成的数据,查表后的结果
|
||||||
|
}
|
||||||
|
|
||||||
|
// 百家学宫加成
|
||||||
|
class SchoolAttr {
|
||||||
|
@prop({ required: true })
|
||||||
|
hid: number; // 武将id
|
||||||
|
@prop({ required: true })
|
||||||
|
attrId: number; // 属性id
|
||||||
|
@prop({ required: true })
|
||||||
|
value: number; // 百家学宫有多个武将,单独拎出来方便计算,计算之后结果存到globaAttrs的global1
|
||||||
|
}
|
||||||
|
|
||||||
|
// 名将谱加成
|
||||||
|
class ScrollAttr {
|
||||||
|
@prop({ required: true })
|
||||||
|
hid: number; // 武将id
|
||||||
|
@prop({ required: true })
|
||||||
|
attrId: number; // 属性id
|
||||||
|
@prop({ required: true })
|
||||||
|
value: number; // 百家学宫有多个武将,单独拎出来方便计算,计算之后结果存到globaAttrs的global1
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 属性表
|
||||||
|
*/
|
||||||
|
|
||||||
|
@index({ roleId: 1 })
|
||||||
|
@index({ roleId: 1 })
|
||||||
|
|
||||||
|
export default class RoleCe extends BaseModel {
|
||||||
|
|
||||||
|
@prop({ required: true })
|
||||||
|
roleId: string; // 角色 id
|
||||||
|
|
||||||
|
@prop({ required: true, type: GlobalAttr, _id: false })
|
||||||
|
globalAttrs: GlobalAttr[]
|
||||||
|
|
||||||
|
@prop({ required: true, type: HeroAttr, _id: false })
|
||||||
|
heroAttrs: HeroAttr[]
|
||||||
|
|
||||||
|
@prop({ required: true, type: EquipAttr, _id: false })
|
||||||
|
equipAttrs: EquipAttr[]
|
||||||
|
|
||||||
|
@prop({ required: true, type: SchoolAttr, _id: false })
|
||||||
|
schoolAttr: SchoolAttr[];
|
||||||
|
|
||||||
|
@prop({ required: true, type: ScrollAttr, _id: false })
|
||||||
|
scrollAttrs: ScrollAttr[];
|
||||||
|
|
||||||
|
public static async findByRoleId(roleId: string) {
|
||||||
|
let result: RoleCeType[] = await RoleCeModel.find({ roleId }).lean();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export const RoleCeModel = getModelForClass(RoleCe);
|
||||||
|
|
||||||
|
export interface RoleCeType extends Pick<DocumentType<RoleCe>, keyof RoleCe> { };
|
||||||
|
export type RoleCeUpdate = Partial<RoleCeType>;
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
import BaseModel from './BaseModel';
|
import BaseModel from './BaseModel';
|
||||||
import { index, getModelForClass, prop, DocumentType, modelOptions } from '@typegoose/typegoose';
|
import { index, getModelForClass, prop, DocumentType, modelOptions } from '@typegoose/typegoose';
|
||||||
|
import { gameData } from '../pubUtils/data';
|
||||||
@index({ roleId: 1, id: 1 })
|
@index({ roleId: 1, id: 1 })
|
||||||
@index({ seqId: 1 })
|
@index({ seqId: 1 })
|
||||||
@modelOptions({ schemaOptions: { id: false } })
|
@modelOptions({ schemaOptions: { id: false } })
|
||||||
@@ -28,6 +29,15 @@ export default class Skin extends BaseModel {
|
|||||||
return rec;
|
return rec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static getInitInfo(hid: number): SkinUpdate {
|
||||||
|
let dicHero = gameData.hero.get(hid);
|
||||||
|
let dicFashion = gameData.fashion.get(dicHero.initialSkin)
|
||||||
|
const doc = new SkinModel();
|
||||||
|
const update = { ...doc.toJSON(), id: dicFashion.id, skinId: dicFashion.heroId, skinName: dicFashion.name, hid};
|
||||||
|
delete update._id;
|
||||||
|
return update
|
||||||
|
}
|
||||||
|
|
||||||
public static async insertSkins(roleId: string, roleName: string, skinInfos: SkinUpdate[]) {
|
public static async insertSkins(roleId: string, roleName: string, skinInfos: SkinUpdate[]) {
|
||||||
let insertInfos: SkinUpdate[] = [];
|
let insertInfos: SkinUpdate[] = [];
|
||||||
for(let skinInfo of skinInfos) {
|
for(let skinInfo of skinInfos) {
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
import { HERO_SYSTEM_TYPE, ABI_TYPE, HERO_CE_RATIO, LINEUP_NUM, TALENT_RELATION_TYPE } from '../consts';
|
import { HERO_SYSTEM_TYPE, ABI_TYPE, HERO_CE_RATIO, LINEUP_NUM, TALENT_RELATION_TYPE } from '../consts';
|
||||||
|
|
||||||
import { cal, deepCopy, getAllAttrStage, reduceCe } from './util';
|
import { cal, calculatetopLineup, deepCopy, getAllAttrStage, reduceCe } from './util';
|
||||||
import { HeroModel, HeroType, HeroUpdate, CeAttrData, EPlace, Stone, Talent } from '../db/Hero';
|
import { HeroModel, HeroType, HeroUpdate, CeAttrData, EPlace, Stone, Talent } from '../db/Hero';
|
||||||
import { RoleModel, RoleType, RoleUpdate, CeAttrDataRole } from '../db/Role';
|
import { RoleModel, RoleType, RoleUpdate, CeAttrDataRole } from '../db/Role';
|
||||||
import { AttributeCal } from '../domain/roleField/attribute';
|
import { AttributeCal } from '../domain/roleField/attribute';
|
||||||
@@ -209,53 +209,6 @@ export async function calPlayerCe(hero: HeroType, update: HeroUpdate, type: numb
|
|||||||
return heroAttrs;
|
return heroAttrs;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 计算最强阵容战力
|
|
||||||
* @param role
|
|
||||||
* @param hid
|
|
||||||
* @param ce
|
|
||||||
* @param heroId
|
|
||||||
*/
|
|
||||||
export async function calculatetopLineup(role: RoleType, hid?: number, ce?: number, heroId?: string) {
|
|
||||||
let topLineup = role?.topLineup || new Array();
|
|
||||||
if(!hid) { // 直接重新排
|
|
||||||
let heroes = await HeroModel.getTopHero(role.roleId, LINEUP_NUM);
|
|
||||||
topLineup = heroes.map(cur => { return { hid: cur.hid, ce: cur.ce, hero: cur._id } });
|
|
||||||
} else {
|
|
||||||
topLineup.sort((a, b) => { return b.ce - a.ce }); // 0-6,最大-最小
|
|
||||||
let index = topLineup.findIndex(cur => cur.hid == hid);
|
|
||||||
if(index != -1 && !heroId) {
|
|
||||||
let heroes = await HeroModel.getTopHero(role.roleId, LINEUP_NUM);
|
|
||||||
topLineup = heroes.map(cur => { return { hid: cur.hid, ce: cur.ce, hero: cur._id } });
|
|
||||||
} else {
|
|
||||||
if (index == -1) { // 不在最强列表
|
|
||||||
if (topLineup.length < LINEUP_NUM) { // 不满6人
|
|
||||||
topLineup.push({ hid, ce, hero: heroId });
|
|
||||||
} else if (topLineup.length == LINEUP_NUM) {
|
|
||||||
if (ce > topLineup[topLineup.length - 1].ce) { // 跻身最强6人
|
|
||||||
topLineup.pop();
|
|
||||||
topLineup.push({ hid, ce, hero: heroId });
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
topLineup.splice(LINEUP_NUM, topLineup.length - LINEUP_NUM);
|
|
||||||
}
|
|
||||||
} else { // 原来就是最强6人
|
|
||||||
if (ce < topLineup[topLineup.length - 1].ce) { // 滑出最强
|
|
||||||
let heroes = await HeroModel.getTopHero(role.roleId, LINEUP_NUM);
|
|
||||||
topLineup = heroes.map(cur => { return { hid: cur.hid, ce: cur.ce, hero: cur._id } });
|
|
||||||
} else {
|
|
||||||
topLineup[index].ce = ce;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let topLineupCe = topLineup.reduce((pre, cur) => {
|
|
||||||
return pre + cur.ce
|
|
||||||
}, 0);
|
|
||||||
|
|
||||||
return { topLineup, topLineupCe };
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 添加皮肤全局加成
|
* 添加皮肤全局加成
|
||||||
|
|||||||
@@ -6,13 +6,14 @@ import { isNumber } from 'underscore';
|
|||||||
const csprng = require('csprng');
|
const csprng = require('csprng');
|
||||||
import fs = require('fs');
|
import fs = require('fs');
|
||||||
import path = require('path');
|
import path = require('path');
|
||||||
import { HERO_CE_RATIO, ABI_STAGE, GACHA_TO_FLOOR, REFRESH_TIME, ROBOT_SYS_TYPE, ITEM_CHANGE_REASON, WAR_TYPE } from '../consts';
|
import { HERO_CE_RATIO, ABI_STAGE, GACHA_TO_FLOOR, REFRESH_TIME, ROBOT_SYS_TYPE, ITEM_CHANGE_REASON, WAR_TYPE, LINEUP_NUM } from '../consts';
|
||||||
|
|
||||||
import { findIndex } from 'underscore';
|
import { findIndex } from 'underscore';
|
||||||
import { getTimeFunM } from './timeUtil';
|
import { getTimeFunM } from './timeUtil';
|
||||||
import { Floor } from '../domain/activityField/gachaField';
|
import { Floor } from '../domain/activityField/gachaField';
|
||||||
import { WhiteListModel } from '../db/RegionWhiteList';
|
import { WhiteListModel } from '../db/RegionWhiteList';
|
||||||
import { RewardInter } from './interface';
|
import { RewardInter } from './interface';
|
||||||
|
import { RoleType } from '../db/Role';
|
||||||
const randomName = require("chinese-random-name");
|
const randomName = require("chinese-random-name");
|
||||||
const moment = require('moment');
|
const moment = require('moment');
|
||||||
const crypto = require('crypto');
|
const crypto = require('crypto');
|
||||||
@@ -788,3 +789,59 @@ export function stringToRewardInter(rewardStr: string): Array<RewardInter> {
|
|||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function addToMap<T>(map: Map<T, number>, id: T, value: number) {
|
||||||
|
if(!map.has(id)) {
|
||||||
|
map.set(id, value);
|
||||||
|
} else {
|
||||||
|
map.set(id, map.get(id) + value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计算最强阵容战力
|
||||||
|
* @param role
|
||||||
|
* @param hid
|
||||||
|
* @param ce
|
||||||
|
* @param heroId
|
||||||
|
*/
|
||||||
|
export async function calculatetopLineup(role: RoleType, hid?: number, ce?: number, heroId?: string) {
|
||||||
|
let topLineup = role?.topLineup || new Array();
|
||||||
|
if(!hid) { // 直接重新排
|
||||||
|
let heroes = await HeroModel.getTopHero(role.roleId, LINEUP_NUM);
|
||||||
|
topLineup = heroes.map(cur => { return { hid: cur.hid, ce: cur.ce, hero: cur._id } });
|
||||||
|
} else {
|
||||||
|
topLineup.sort((a, b) => { return b.ce - a.ce }); // 0-6,最大-最小
|
||||||
|
let index = topLineup.findIndex(cur => cur.hid == hid);
|
||||||
|
if(index != -1 && !heroId) {
|
||||||
|
let heroes = await HeroModel.getTopHero(role.roleId, LINEUP_NUM);
|
||||||
|
topLineup = heroes.map(cur => { return { hid: cur.hid, ce: cur.ce, hero: cur._id } });
|
||||||
|
} else {
|
||||||
|
if (index == -1) { // 不在最强列表
|
||||||
|
if (topLineup.length < LINEUP_NUM) { // 不满6人
|
||||||
|
topLineup.push({ hid, ce, hero: heroId });
|
||||||
|
} else if (topLineup.length == LINEUP_NUM) {
|
||||||
|
if (ce > topLineup[topLineup.length - 1].ce) { // 跻身最强6人
|
||||||
|
topLineup.pop();
|
||||||
|
topLineup.push({ hid, ce, hero: heroId });
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
topLineup.splice(LINEUP_NUM, topLineup.length - LINEUP_NUM);
|
||||||
|
}
|
||||||
|
} else { // 原来就是最强6人
|
||||||
|
if (ce < topLineup[topLineup.length - 1].ce) { // 滑出最强
|
||||||
|
let heroes = await HeroModel.getTopHero(role.roleId, LINEUP_NUM);
|
||||||
|
topLineup = heroes.map(cur => { return { hid: cur.hid, ce: cur.ce, hero: cur._id } });
|
||||||
|
} else {
|
||||||
|
topLineup[index].ce = ce;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let topLineupCe = topLineup.reduce((pre, cur) => {
|
||||||
|
return pre + cur.ce
|
||||||
|
}, 0);
|
||||||
|
|
||||||
|
return { topLineup, topLineupCe };
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user