diff --git a/game-server/app/servers/role/handler/heroHandler.ts b/game-server/app/servers/role/handler/heroHandler.ts index 5c7307731..32d559aff 100644 --- a/game-server/app/servers/role/handler/heroHandler.ts +++ b/game-server/app/servers/role/handler/heroHandler.ts @@ -255,7 +255,7 @@ export class HeroHandler { let {fragmentNum, consume} = curDicHeroStar; let consumeArr = decodeStr('cost', consume); - console.log(JSON.stringify([{id: pieceId, count: fragmentNum}, ...consumeArr])) + // console.log(JSON.stringify([{id: pieceId, count: fragmentNum}, ...consumeArr])) let costResult = await handleCost(roleId, sid, [{id: pieceId, count: fragmentNum}, ...consumeArr]); if(!costResult) return resResult(STATUS.ROLE_MATERIAL_NOT_ENOUGH); diff --git a/game-server/app/services/playerCeService.ts b/game-server/app/services/playerCeService.ts index cd1efa7b3..b703b63c4 100644 --- a/game-server/app/services/playerCeService.ts +++ b/game-server/app/services/playerCeService.ts @@ -2,31 +2,35 @@ * 体力系统 */ -import { ActionPointModel } from '../db/ActionPoint'; -import { HERO_SYSTEM_TYPE } from '../consts/consts'; +import { HERO_SYSTEM_TYPE, WAR_JSON_ATTRIBUTE_TYPE } from '../consts/consts'; import { pinus } from 'pinus'; import { STATUS } from '../consts/statusCode'; + import { resResult } from '../pubUtils/util'; -import { HeroModel } from '../db/Hero'; +import Hero from '../db/Hero'; import { RoleModel } from '../db/Role'; -import { getJobInfoById, getJobByGradeAndClass, getHeroInfoById } from '../pubUtils/gamedata'; -import { HEROTARIN, CE_RATIO} from '../consts/abilityConst'; +import { getJobInfoById, getJobByGradeAndClass, getHeroInfoById, getHeroStar, getHeroWake } from '../pubUtils/gamedata'; +import { HEROTARIN, CE_RATIO, ABI_TYPE_TO_STAGE, ABI_STAGE} from '../consts/abilityConst'; +import { CeAttrData } from '../db/BaseModel'; const HERO_CE_RATIO = 100; //战力计算TODO export function calPlayerCe(hero: any, type: number, args: Array) { let incCe = 0; let incArr = {}; - let reIncAttr; + let reIncAttr; // {"hp": {"base": number, "fixUp": number, "ratioUp": number}} if (type == HERO_SYSTEM_TYPE.STAR) { - reIncAttr = calHeroStarIncAttr(hero, args); + reIncAttr = calHeroStarIncAttr(hero, args); // 返回 计算后的值 } else if (type == HERO_SYSTEM_TYPE.TRAIN) { reIncAttr = calHeroTrainIncAttr(hero); } for (let attrName in reIncAttr) { + let originalAttrData: CeAttrData = hero.ceAttr[attrName]; + let oldCe = originalAttrData.fixUp * HERO_CE_RATIO + originalAttrData.base *(HERO_CE_RATIO + originalAttrData.ratioUp) + for (let attrKey in reIncAttr[attrName]) { - hero.CeAttr[attrName][attrKey] += parseInt(reIncAttr[attrName][attrKey]); + hero.CeAttr[attrName][attrKey] = parseInt(reIncAttr[attrName][attrKey]); } - incArr[attrName] = reIncAttr[attrName].fixUp * HERO_CE_RATIO + reIncAttr[attrName].base *(HERO_CE_RATIO + reIncAttr[attrName].ratioUp); //计算属性 + incArr[attrName] = reIncAttr[attrName].fixUp * HERO_CE_RATIO + reIncAttr[attrName].base *(HERO_CE_RATIO + reIncAttr[attrName].ratioUp) - oldCe; //计算属性 incCe += incArr[attrName] * CE_RATIO[attrName]; } hero.ce += incCe; @@ -37,6 +41,7 @@ export function calPlayerCe(hero: any, type: number, args: Array) { export async function calPlayerCeAndSave(sid: string, roleId: string, heros: Array, type?: number, args?: Array) { let incPlayerCe = 0; let pushHeros = []; + for (let hero of heros) { let incHeroCe = calPlayerCe(hero, type, args); incPlayerCe += incHeroCe; @@ -47,17 +52,58 @@ export async function calPlayerCeAndSave(sid: string, roleId: string, heros: Arr incHeroCe : incHeroCe, }); } - let role = await RoleModel.findOne({ roleId }); + let role = await RoleModel.findByRoleId(roleId); role.ce += incPlayerCe; - await role.save(); + await RoleModel.updateRoleInfo(roleId, role); //下发战力 let uids = [{ uid: roleId, sid }]; pinus.app.get('channelService').pushMessageByUids('onPlayerCeUpdate', resResult(STATUS.SUCCESS, { ce: role.ce, heros: pushHeros, topFiveCe: 0 }), uids); return heros; } -export function calHeroStarIncAttr(hero: any, args: Array) { - return {};//属性增量可以是多个 +export function calHeroStarIncAttr (hero: Hero, _args: Array) { + let {star, starStage, quality, colorStar, colorStarStage, ceAttr} = hero; + let res = {}; + const dicHero = getHeroInfoById(hero.hid); + + const isWake = colorStar > 0; // 是否觉醒,只要激活了觉醒,彩星就会 > 1 + + let attrs = new Array(); // 有升级的属性 1-hp 2-atk 3-def 4-mdef 5-agi 6-luk + if(isWake) { + if(colorStar == 1 && colorStarStage == ABI_STAGE.START) { // 当第一次觉醒时,一口气修改全部属性 + for(let stage = ABI_STAGE.START + 1; stage <= ABI_STAGE.END; stage++) { + attrs.push(stage) + }; + colorStar = colorStar -1; // 当第一次觉醒时,存的是1,读表的是上一行0 + } else { // 觉醒一次,相应的属性 + if(colorStarStage == ABI_STAGE.START) { // 当升一级的时候,存储会存0,但加的是6,读表读的是上一行 + colorStarStage = ABI_STAGE.END; colorStar = colorStar -1; + } + attrs.push(colorStarStage); + } + } else { + if(starStage == ABI_STAGE.START) { // 当升一级的时候,存储会存0,但加的是6,读表读的是上一行 + starStage = ABI_STAGE.END; star = star -1; + } + attrs.push(starStage); + } + const dicStar = isWake? getHeroWake(quality, colorStar): getHeroStar(quality, star); // 星级表 + + for(let stage of attrs) { + + let targetAttrId = getFieldByStage(stage, hero.job); // 转换为17维的属性id + let heroAttr = dicHero.baseAbilityArr[targetAttrId]; // 武将表hp等 + let heroUpAttr = dicHero.baseAbilityUpArr[targetAttrId]; // 武将表hp_up等 + + let starUp = dicStar.ceAttr.get(stage); + let newBase = heroAttr + hero.lv * (heroUpAttr + starUp); + let field = WAR_JSON_ATTRIBUTE_TYPE[targetAttrId]; + let ceAttrData: CeAttrData = ceAttr[field]; // 存表中的属性下的base,fixup,ratioup + let {ratioUp = 0, fixUp = 0} = ceAttrData; + res[field] = { base: newBase, ratioUp, fixUp}; // base变动,增量为△base * ratio + 0 + } + + return res;//属性增量可以是多个 } export function calHeroTrainIncAttr(hero: any) { @@ -74,3 +120,14 @@ export function calHeroTrainIncAttr(hero: any) { } return res; } + +// 根据存在升星表等的stage字段的id对应17维id +function getFieldByStage(stage: number, jobid: number) { + let targetAttrId = ABI_TYPE_TO_STAGE.get(stage); + if(typeof targetAttrId === 'number') { + return targetAttrId + } else { + const dicJob = getJobInfoById(jobid); + return targetAttrId(dicJob.type); + } +} diff --git a/shared/consts/abilityConst.ts b/shared/consts/abilityConst.ts index 687be9104..480bd43f6 100644 --- a/shared/consts/abilityConst.ts +++ b/shared/consts/abilityConst.ts @@ -4,7 +4,10 @@ * 属性 id */ -export enum ABI_TYPE { + +import { JOB_TYPE } from "./consts"; + +export enum ABI_TYPE{ /**生命 */ ABI_HP = 1, /**物攻 */ @@ -90,3 +93,11 @@ export const CE_RATIO = { "bloodSuck": 0, }; + export const ABI_TYPE_TO_STAGE = new Map number)>([ + [ABI_STAGE.HP, ABI_TYPE.ABI_HP], + [ABI_STAGE.ATK, (jobType:number) => { return jobType == JOB_TYPE.PHYSIC?ABI_TYPE.ABI_ATK: ABI_TYPE.ABI_MATK}], + [ABI_STAGE.DEF, ABI_TYPE.ABI_DEF], + [ABI_STAGE.MDEF, ABI_TYPE.ABI_MDEF], + [ABI_STAGE.AGI, ABI_TYPE.ABI_AGI], + [ABI_STAGE.LUK, ABI_TYPE.ABI_LUK] + ]); diff --git a/shared/consts/consts.ts b/shared/consts/consts.ts index 4fae0d4f9..c44335c56 100644 --- a/shared/consts/consts.ts +++ b/shared/consts/consts.ts @@ -339,4 +339,9 @@ export const HERO_GROW_MAX = { STAR: 6, COLORSTAR: 6, QUALITY: 3 +} + +export const JOB_TYPE = { + PHYSIC: 1, + MAGIC: 2 } \ No newline at end of file diff --git a/shared/db/BaseModel.ts b/shared/db/BaseModel.ts index 094dace53..21b304c37 100644 --- a/shared/db/BaseModel.ts +++ b/shared/db/BaseModel.ts @@ -24,7 +24,7 @@ export default class BaseModel extends TimeStamps { updatedAt: Date } -class CeAttrData { +export class CeAttrData { @prop({ required: true }) base?: number; @prop({ required: true }) diff --git a/shared/db/Hero.ts b/shared/db/Hero.ts index a41add7d8..2b6d9eccf 100644 --- a/shared/db/Hero.ts +++ b/shared/db/Hero.ts @@ -10,9 +10,7 @@ import { COUNTER } from '../consts/consts'; class Connect { @prop({ required: true }) - shipId: number; - @prop({ required: true }) - level: number; + id: number; } class Skin { @@ -65,9 +63,9 @@ export default class Hero extends BaseModel { @prop({ required: true, default: 0 }) ce: number; // 武将战力 @prop({ required: true, default: 0 }) - historyCe: number; // 武将历史最高战力存储的是实际10000倍数据 - @prop({required: true, default: {} }) - ceAttr: CeAttr; // 影响战力的属性存储的是实际10000倍数据 + historyCe: number; // 武将历史最高战力 + @prop({required: true }) + ceAttr: CeAttr; // 影响战力的属性 @prop({ required: true, default: 1 }) star: number; // 星级 @@ -97,7 +95,7 @@ export default class Hero extends BaseModel { @prop({ ref: Equip, type: mongoose.Schema.Types.ObjectId }) equips: Ref[]; // 武将装备引用数组 - + public static async findByRole(roleId: string, lean = true) { const heros = await HeroModel.find({ roleId }).populate('equips').lean(lean); return heros || []; diff --git a/shared/pubUtils/gamedata.ts b/shared/pubUtils/gamedata.ts index 1f878487a..9e391add5 100644 --- a/shared/pubUtils/gamedata.ts +++ b/shared/pubUtils/gamedata.ts @@ -1,6 +1,6 @@ import fs = require('fs'); import path = require('path'); -import { ABI_TYPE } from '../consts/abilityConst'; +import { ABI_TYPE, ABI_STAGE } from '../consts/abilityConst'; import { decodeIdCntArrayStr, getRandEelm } from './util'; import { IT_TYPE } from '../consts/consts'; @@ -30,6 +30,26 @@ const blueprtCompose = new Map(); const fiendShips = new Map(); const fashions = new Map(); const fiendShipHidAandIds = new Map(); + + +interface dicStar { + id: number; + quality: number; + star: number; + advanceUpFragmentNum: number; + ceAttr: Map +} +const heroStarList = new Map(); +interface dicWake { + id: number; + quality: number; + star: number; + fragmentNum: number; + consume: string; + ceAttr: Map +} +const heroWakeList = new Map(); + function parseWarData() { let result = null; for (let filename of wars) { @@ -297,6 +317,43 @@ function initData (folder: string) { }); } +function parseHeroStar() { + const file = 'dic_zyz_hero_star'; + const data = gamedata['jsons'][file] || []; + data.forEach(elem => { + if (elem.id) { + let ceAttr = new Map(); + ceAttr.set(ABI_STAGE.HP, elem.hp_up); + ceAttr.set(ABI_STAGE.ATK, elem.atk_up); + ceAttr.set(ABI_STAGE.DEF, elem.def_up); + ceAttr.set(ABI_STAGE.MDEF, elem.mdef_up); + ceAttr.set(ABI_STAGE.AGI, elem.agi_up); + ceAttr.set(ABI_STAGE.LUK, elem.luk_up); + + heroStarList.set(`${elem.quality}_${elem.star}`,{ceAttr, ...elem}); + } + }); +} + + +function parseHeroWake() { + const file = 'dic_zyz_hero_wake'; + const data = gamedata['jsons'][file] || []; + data.forEach(elem => { + if (elem.id) { + let ceAttr = new Map(); + ceAttr.set(ABI_STAGE.HP, elem.hp_up); + ceAttr.set(ABI_STAGE.ATK, elem.atk_up); + ceAttr.set(ABI_STAGE.DEF, elem.def_up); + ceAttr.set(ABI_STAGE.MDEF, elem.mdef_up); + ceAttr.set(ABI_STAGE.AGI, elem.agi_up); + ceAttr.set(ABI_STAGE.LUK, elem.luk_up); + + heroWakeList.set(`${elem.quality}_${elem.star}`,{ceAttr, ...elem}); + } + }); +} + function parseData() { parseWarData(); parseTowerData(); @@ -316,6 +373,8 @@ function parseData() { parseFashions(); parseFiendShips(); parseFiendShipLevels(); + parseHeroStar(); + parseHeroWake(); } initData('jsons'); // 加载一般json @@ -498,4 +557,12 @@ export function getFriendShipLevels() { export function getJobByGradeAndClass(jobClass: number, grade: number) { return jobClassAndgrades.get(jobClass +'_' + grade); +} + +export function getHeroStar(quality: number, star: number) { + return heroStarList.get(`${quality}_${star}`); +} + +export function getHeroWake(quality: number, star: number) { + return heroWakeList.get(`${quality}_${star}`); } \ No newline at end of file