import { ABI_STAGE, ABI_STAGE_TO_TYPE, ABI_TYPE, ABI_TYPE_MAIN, LINEUP_NUM, SEID_TYPE, TALENT_RELATION_TYPE } from "../../consts"; import { Connect, EPlace, HeroSkin, HeroType, HeroUpdate, Stone, Talent } from "../../db/Hero"; import { JewelType } from "../../db/Jewel"; import { RoleUpdate, Teraph } from "../../db/Role"; import { AttrCell, Attribute, EquipAttr, HeroAttr, RoleCeType, SchoolAttr, ScrollAttr } from "../../db/RoleCe"; import { TopHero } from "../../domain/dbGeneral"; import { AttributeCal } from "../../domain/roleField/attribute"; import { gameData, getEquipQualityIdByEquipIdAndPoint, getEquipStarAttrByStage, getEquipStrenthenAttr, getEquipSuitByHero, getFriendShipByIdAndLv, getHeroStarByQuality, getHeroWakeByQuality, getJewelConditionByLvAndSeId, getJobByGradeAndClass, getSchoolRateByStar, getScollByStar, getTeraph } from "../../pubUtils/data"; import { DicRandomEffectPool } from "../../pubUtils/dictionary/DicRandomEffectPool"; import { DicSe } from "../../pubUtils/dictionary/DicSe"; import { addToMap, deepCopy } from "../../pubUtils/util"; export class CalCe { roleId: string; originCes: Map = new Map(); // hid => ce resultCes: Map = new Map(); // hid => ce data: CalCeData; attrsByHid: Map = new Map(); originTopHeroCe: number; constructor(roleId: string) { this.roleId = roleId; } public setRoleCe(roleCe: RoleCeType) { this.data = new CalCeData(roleCe) this.originCes = this.calHeroCe(); this.originTopHeroCe = this.getTopLineup().topLineupCe; } public clearRoleCe() { this.data = new CalCeData(null); } public getRoleCeTable() { let attributes: Attribute[] = []; for(let [hid, attrs] of this.attrsByHid) { attributes.push({ hid, attrs }) } return this.data.getRoleCeTable(this.roleId, attributes); } public calHeroCe() { let attrs = new Map(); // hid => [{attrId, val}] for(let [hid ] of this.data.heroAttrsByHid) { let lv = this.data.heroLv.get(hid)||1; for(let attrId = ABI_TYPE.ABI_HP; attrId < ABI_TYPE.ABI_MAX; attrId++) { if(!this.data.heroAttrs.has(`${hid}_${attrId}`) && !this.data.globalAttrs.has(attrId)) continue; let { mainBase = 0, subBase = 0, job = 0, starUp = 0, connect = 0, talent = 0, equipQuality = 0, equipStrength = 0, equipStar = 0, equipSuit = 0, jewel = 0, stone = 0 } = this.data.heroAttrs.get(`${hid}_${attrId}`)||{}; let { school = 0, teraph = 0, title = 0, scroll = 0, skin = 0 } = this.data.getGlobalAttrById(attrId)||{}; let val = 0, str = ''; if(ABI_TYPE_MAIN.indexOf(attrId) != -1) { // {[ hp1 + lv * hp2 ] * ( 1 + hp5 ) + [( hp6 + hp7 ) * ( 1 + hp8 )]} * ( 1 + hp9 ) + hp10 + hp11 val = (( mainBase + job + lv * starUp ) * ( 1 + connect/100 ) + (( equipQuality + equipStrength ) * ( 1 + ( equipStar/100 + equipSuit/100 )))) * ( 1 + jewel/100 + school/100 + talent/100 + skin/100 ) + stone + teraph + title + scroll; str += `{[${mainBase}+${job}+${lv}*${starUp}]* ( 1 + ${connect}/100) + [(${equipQuality}+${equipStrength}) * ( 1 + ${equipStar}/100+${equipSuit}/100)]} * (1+${jewel}/100+${school}/100+${talent}/100+${skin}/100 )+${stone}+${teraph}+${title}+${scroll}`; } else { // attr1 + attr2 + attr4 + attr5 + attr6 + attr7 + attr9 val = subBase + job + teraph + school + title + jewel + equipStar; str += `${subBase}+${job}+${teraph}+${school}+${title}+${jewel}+${equipStar}`; } if(!attrs.has(hid)) attrs.set(hid, []); attrs.get(hid).push({ id: attrId, val, str }); } } let result = new Map(); for(let [hid, arr] of attrs) { let lv = this.data.heroLv.get(hid)||1; let obj = new AttributeCal(); obj.setLv(lv); obj.setByWarJson(arr); let ce = obj.calCe(); this.resultCes.set(hid, ce); result.set(hid, ce); this.attrsByHid.set(hid, arr); } return result; } public calSingleGlobalPartCe(hid: number, field: 'teraph'|'scroll') { let arr: { id: number, val: number }[] = []; for(let [attrId, globalAttr] of this.data.globalAttrs) { arr.push({ id: attrId, val: globalAttr[field]||0 }); } let lv = this.data.heroLv.get(hid)||1; let obj = new AttributeCal(); obj.setLv(lv); obj.setByWarJson(arr); return obj.calCe(); } public getCeInc() { let ceResult = this.calHeroCe(); // console.log('##### ceResult', ceResult, 'originCes', this.originCes) let heroCe = new Map(); let roleInc = 0; for(let [hid, ce] of ceResult) { let originCe = this.originCes.get(hid)||0; if(ce != originCe) { heroCe.set(hid, { inc: ce - originCe, origin: originCe, ce }); roleInc += ce - originCe; this.data.setHistoryCe(hid, ce); } } return { heroCe, roleInc } } public setResultHero(hero: HeroType) { this.data.setResultHero(hero); } public getResultCeArr() { let arr: { hid: number, ce: number }[] = []; for(let [ hid, ce ] of this.resultCes) { arr.push({ hid, ce }); } arr.sort((a, b) => b.ce - a.ce); return arr; } public getTopLineup() { let topLineup: TopHero[] = [], topLineupCe = 0; let arr = this.getResultCeArr(); for(let i = 0; i < LINEUP_NUM; i++) { if(arr[i]) { let { hid, ce } = arr[i]; topLineup.push({ hid, ce, hero: this.data.heroObjectId.get(hid) }); topLineupCe += ce; } } return { topLineup, topLineupCe, hasTopCeChange: topLineupCe == this.originTopHeroCe }; } // 玩家等级 public setRoleLv(lv: number) { this.data.roleLv = lv; } // 武将基础&成长 public setHeroBase(hid: number, skinId: number) { this.data.clearHeroAttrByHid(hid, 'mainBase'); let dicHero = gameData.hero.get(skinId); for(let [attrId, value] of dicHero.baseAbilityArr) { let heroAttr = this.data.getHeroAttrByHidAndId(hid, attrId); heroAttr.mainBase = value; } } // 武将等级 public setHeroLv(hid: number, lv: number) { this.data.heroLv.set(hid, lv); } // 星级相关 public setHeroStar(hid: number, job: number, quality: number, star: number, starStage: number, colorStar: number, colorStarStage: number) { this.data.clearHeroAttrByHid(hid, 'starUp'); let dicHero = gameData.hero.get(hid); let dicJob = gameData.job.get(job); let jobClass = dicJob.job_class; const isWake = colorStar > 0; // 是否觉醒,只要激活了觉醒,彩星就会 > 1 const dicStar = isWake ? getHeroWakeByQuality(jobClass, dicHero.quality, colorStar) : getHeroStarByQuality(jobClass, quality, star); // 星级表 const dicPreStar = isWake? getHeroWakeByQuality(jobClass, dicHero.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.data.getHeroAttrByHidAndId(hid, attrId); heroAttr.starUp = value; }; } // 职业基础 public setJob(hid: number, job: number, jobStage: number) { this.data.clearHeroAttrByHid(hid, 'job'); const dicJob = gameData.job.get(job); let ceAttr = dicJob.ceAttr.get(jobStage)||[]; for(let { id, attr } of ceAttr) { let heroAttr = this.data.getHeroAttrByHidAndId(hid, id); heroAttr.job = attr; } for(let { id, val } of dicJob.baseSubAttr) { let heroAttr = this.data.getHeroAttrByHidAndId(hid, id); heroAttr.subBase = val; } } // 羁绊 public setConnection(hid: number, connections: Connect[]) { this.data.clearHeroAttrByHid(hid, 'connect'); let map = new Map(); // attrId => val; for(let { shipId, level = 0 } of connections) { let currentShip = getFriendShipByIdAndLv(hid, shipId, level); if (currentShip) { for (let { id, number: val } of currentShip.attributes) { if(!map.has(id)) { map.set(id, val); } else { map.set(id, map.get(id) + val); } } } } for(let [id, val] of map) { let heroAttr = this.data.getHeroAttrByHidAndId(hid, id); heroAttr.connect = val; } } // 第一次获得皮肤 public setAddSkin(skinId: number) { let addSkin = gameData.fashion.get(skinId); for (let { id, number: val } of addSkin.globalAttr) { let globalAttr = this.data.getGlobalAttrById(id); globalAttr.skin += val; } } // 天赋 public setTalent(hid: number, skins: HeroSkin[]) { this.data.clearHeroAttrByHid(hid, 'talent'); let skin = skins.find(cur => cur.enable); let seids = this.getTalentSeid(skin.talent); let { ratioUp } = this.addSeidEffect(seids); for(let [attrId, val] of ratioUp) { let heroAttr = this.data.getHeroAttrByHidAndId(hid, attrId); heroAttr.talent = val; } } public getTalentSeid(talent: Talent[]) { let seids = new Map(); // id, seids for(let { id, level } of talent) { let dicHeroTalent = gameData.heroTalent.get(id); for(let { type, ids} of dicHeroTalent.relation) { if(type == TALENT_RELATION_TYPE.REPLACE) { for(let id of ids) { seids.delete(id); } } } for(let { lv, seid } of dicHeroTalent.level) { if(level == lv) { if(!seids.has(id)) seids.set(id, []); seids.get(id).push(seid, 0); } } } let result: number[] = []; for(let [_, ids] of seids) { result.push(...ids); } return result; } // 装备升品 public setEquipQuality(hid: number, eplaceId: number, equipId: number, quality: number, qualityStage: number) { this.data.clearHeroAttrByHid(hid, 'equipQuality'); this.data.clearEquipAttrByHidAndEplace(hid, eplaceId, 'equipQuality'); let dicEquipQuality = getEquipQualityIdByEquipIdAndPoint(equipId, quality, qualityStage); let map = new Map(); // attrId => val for(let { id, num } of dicEquipQuality.attribute) { if(!map.has(id)) { map.set(id, num); } else { map.set(id, map.get(id) + num); } } for(let [id, val] of map) { let equipAttr = this.data.getEquipAttrByHidAndId(hid, eplaceId, id); equipAttr.equipQuality = val; } let equips = this.data.getEquipAttrsByHid(hid); for(let { hid, attrId, equipQuality } of equips) { let heroAttr = this.data.getHeroAttrByHidAndId(hid, attrId); heroAttr.equipQuality += equipQuality; } } public clearEquip(hid: number) { this.data.clearHeroAttrByHid(hid, 'equipQuality'); this.data.clearEquipAttrByHid(hid, 'equipQuality'); this.data.clearHeroAttrByHid(hid, 'equipStrength'); this.data.clearEquipAttrByHid(hid, 'equipStrength'); this.data.clearHeroAttrByHid(hid, 'equipStar'); this.data.clearEquipAttrByHid(hid, 'equipStar'); } // 装备强化 public setEquipStrength(hid: number, eplaceId: number, equipId: number, lv: number) { this.data.clearHeroAttrByHid(hid, 'equipStrength'); this.data.clearEquipAttrByHidAndEplace(hid, eplaceId, 'equipStrength'); let dicEquipStrenth = getEquipStrenthenAttr(equipId, lv); let map = new Map(); // attrId => val for(let { id, num } of dicEquipStrenth.attr) { if(!map.has(id)) { map.set(id, num); } else { map.set(id, map.get(id) + num); } } for(let [id, val] of map) { let equipAttr = this.data.getEquipAttrByHidAndId(hid, eplaceId, id); equipAttr.equipStrength = val; } let equips = this.data.getEquipAttrsByHid(hid); for(let { hid, attrId, equipStrength } of equips) { let heroAttr = this.data.getHeroAttrByHidAndId(hid, attrId); heroAttr.equipStrength += equipStrength; } } // 装备精炼(升星) public setEquipStar(hid: number, eplaceId: number, equipId: number, star: number, starStage: number) { this.data.clearHeroAttrByHid(hid, 'equipStar'); this.data.clearEquipAttrByHidAndEplace(hid, eplaceId, 'equipStar'); let dicEquipStar = getEquipStarAttrByStage(equipId, star, starStage); if(dicEquipStar) { let { mainAttr, subAttr } = dicEquipStar; let map = new Map(); // attrId => val for(let { id, num } of [...mainAttr, ...subAttr]) { if(!map.has(id)) { map.set(id, num); } else { map.set(id, map.get(id) + num); } } for(let [id, val] of map) { let equipAttr = this.data.getEquipAttrByHidAndId(hid, eplaceId, id); equipAttr.equipStar = val; } let equips = this.data.getEquipAttrsByHid(hid); for(let { hid, attrId, equipStar } of equips) { let heroAttr = this.data.getHeroAttrByHidAndId(hid, attrId); heroAttr.equipStar += equipStar; } } } // 装备套装 public setEquipSuit(hid: number, skinId: number, ePlace: EPlace[]) { this.data.clearHeroAttrByHid(hid, 'equipSuit'); let dicEquipSuit = getEquipSuitByHero(skinId); let suitStars: number[] = []; for(let equipId of dicEquipSuit.equips) { let equip = ePlace.find(cur => cur.equipId == equipId); suitStars.push(equip? equip.star: 0); } let minStar = Math.min(...suitStars); for(let { star, id, val } of dicEquipSuit.effect) { if(minStar >= star) { let heroAttr = this.data.getHeroAttrByHidAndId(hid, id); heroAttr.equipSuit = val; } } } // 天晶 public setJewel(hid: number, eplaceId: number, stones: Stone[], jewel: JewelType) { this.data.clearHeroAttrByHid(hid, 'jewel'); this.data.clearEquipAttrByHidAndEplace(hid, eplaceId, 'jewel'); let seids: number[] = []; if(jewel) { for(let { id, seid, rand } of jewel.randSe) { if(this.isRandSeUnLock(jewel.id, id, stones)) { seids.push(seid, rand); } } for(let { seid, rand } of jewel.rareSe) { seids.push(seid, rand); } } let { ratioUp } = this.addSeidEffect(seids); let map = new Map(); // attrId => val for(let [id, num] of ratioUp) { if(!map.has(id)) { map.set(id, num); } else { map.set(id, map.get(id) + num); } } for(let [id, val] of map) { let equipAttr = this.data.getEquipAttrByHidAndId(hid, eplaceId, id); equipAttr.jewel = val; } let equips = this.data.getEquipAttrsByHid(hid); for(let { hid, attrId, jewel } of equips) { let heroAttr = this.data.getHeroAttrByHidAndId(hid, attrId); heroAttr.jewel += jewel; } } public isRandSeUnLock(jewelId: number, randSeId: number, stones: Stone[]) { let dicJewel = gameData.jewel.get(jewelId); let dicJewelCondition = getJewelConditionByLvAndSeId(dicJewel.lv, randSeId); let stoneCnt = 0, stoneLv = 0; for(let { stone } of stones) { let dicStone = gameData.stone.get(stone); if(dicStone) { stoneCnt++; stoneLv += dicStone.lv; } } return stoneCnt >= dicJewelCondition.stoneCnt && stoneLv >= dicJewelCondition.stoneLv; } // 地玉 public setStone(hid: number, eplaceId: number, stones: Stone[]) { this.data.clearHeroAttrByHid(hid, 'stone'); this.data.clearEquipAttrByHidAndEplace(hid, eplaceId, 'stone'); let map = new Map(); // attrId => val for(let { stone } of stones) { let dicStone = gameData.stone.get(stone); if(dicStone) { for(let { id, num } of dicStone.attribute) { if(!map.has(id)) { map.set(id, num); } else { map.set(id, map.get(id) + num); } } } } for(let [id, val] of map) { let equipAttr = this.data.getEquipAttrByHidAndId(hid, eplaceId, id); equipAttr.stone = val; } let equips = this.data.getEquipAttrsByHid(hid); for(let { hid, attrId, stone } of equips) { let heroAttr = this.data.getHeroAttrByHidAndId(hid, attrId); heroAttr.stone += stone; } } // 爵位 public setTitle(title: number) { this.data.clearRoleAttr('title'); let dicTitle = gameData.title.get(title)||{ mainAttrValue: new Map(), assiAttrValue: new Map() }; for(let [attrId, value] of dicTitle.mainAttrValue) { let globalAttr = this.data.getGlobalAttrById(attrId); globalAttr.title = value; } for(let [attrId, value] of dicTitle.assiAttrValue) { let globalAttr = this.data.getGlobalAttrById(attrId); globalAttr.title = value; } } // 神像相关 public setTeraph(teraphs: Teraph[]) { this.data.clearRoleAttr('teraph'); let teraphOfAttrId = new Map(); for(let teraph of teraphs) { let dicTeraph = getTeraph(teraph.id, teraph.grade); for(let [attrId, value] of teraph.attr) { // 主属性 let basic = dicTeraph.basicAttrValue.get(attrId)||0; addToMap(teraphOfAttrId, attrId, value + basic); } for(let [attrId, value] of dicTeraph.assiAttrValue) { // 次属性 addToMap(teraphOfAttrId, attrId, value); } } for(let [attrId, value] of teraphOfAttrId) { let globalAttr = this.data.getGlobalAttrById(attrId); globalAttr.teraph = value; } } // 名将谱 public setScroll(hid: number, scrollStar: number, scrollQuality: number, scrollColorStar: number) { this.data.clearScrollAttr(hid); let dicHero =gameData.hero.get(hid); let dicHeroScroll = getScollByStar(dicHero.quality, scrollStar, scrollQuality, scrollColorStar); if(dicHeroScroll) { for(let [attrId, value] of dicHeroScroll.ceAttr) { this.data.setScrollAttrs(hid, attrId, value); this.data.calScrollAttrsToGlobal(attrId); } } } // 百家学宫 public setSchool(isPutOn: boolean, hid: number, schoolId: number, star: number, colorStar: number, quality: number) { this.data.clearSchoolAttr(hid); let dicSchool = gameData.school.get(schoolId); let dicSchoolRate = getSchoolRateByStar(star, colorStar, quality); for (let attrId of dicSchool.upAttribute) { if(ABI_TYPE_MAIN.includes(attrId)) { // 主属性 this.data.setSchoolAttrs(hid, attrId, isPutOn?dicSchoolRate.mainAttrAPerent: 0); } else { this.data.setSchoolAttrs(hid, attrId, isPutOn?dicSchoolRate.assiAttrAddValue: 0); } this.data.calSchoolAttrsToGlobal(attrId); } } // 添加技能增加的被动属性 private addSeidEffect(seidList: number[]) { let fixUp = new Map(), ratioUp = new Map(); 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, id, gainValueArr: [ability, value] } of effectList) { // console.log('##### addToMap type', type, 'id', id, 'ability', ability, 'value', value) if (type == SEID_TYPE.FIX) { // 加值 addToMap(fixUp, ability, value); } else if (type == SEID_TYPE.MAIN_RATIO||type == SEID_TYPE.MAIN_RATIO_2) { // 主属性加百分比 if(ABI_TYPE_MAIN.includes(ability)) { addToMap(ratioUp, ability, value); } } else if (type == SEID_TYPE.SUB_RATIO||type == SEID_TYPE.SUB_RATIO_2) { // 次级属性加百分比 if(!ABI_TYPE_MAIN.includes(ability)) { addToMap(ratioUp, ability, value); } } } 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.MIX) { 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); } } class CalCeData { roleLv: number = 1; // 玩家等级 // 全局 globalAttrs: Map = new Map(); // attrId => GlobalAttr // 武将 heroAttrs: Map = new Map(); // hid+attrId => HeroAttr heroAttrsByHid: Map = new Map(); // hid => [hid+attrId] heroLv: Map = new Map(); heroHistoryCe: Map = new Map(); heroObjectId: Map = new Map(); // 装备 equipAttrs: Map = new Map(); // hid+eplaceId+attrId => EquipAttr equipAttrsByHid: Map = new Map(); // hid => [hid+eplaceId+attrId] equipAttrsByHidAndEplace: Map = new Map(); // hid+eplaceId =>[hid+eplaceId+attrId] equipAttrsByHidAndAttrId: Map = new Map(); // hid+attrId =>[hid+eplaceId+attrId] equipLv: Map = new Map(); // hid+eplaceId => lv // 百家学宫 schoolAttrs: Map = new Map(); // hid + attr => ratio schoolAttrsByAttrId: Map = new Map(); // attrId => hid + attr schoolAttrsByHid: Map = new Map(); // hid => hid + attr // 名将谱 scrollAttrs: Map = new Map(); // hid + attr => ratio scrollAttrsByAttrId: Map = new Map(); // attrId => hid + attr scrollAttrsByHid: Map = new Map(); // hid => hid + attr constructor(roleCe: RoleCeType) { if(roleCe) { this.roleLv = roleCe.roleLv; for(let globalAttr of roleCe.globalAttrs) { let obj = this.getGlobalAttrById(globalAttr.attrId); obj.setByRoleCe(globalAttr); } for(let {hid, lv, attrs, historyCe, objectId } of roleCe.heroAttrs) { this.heroLv.set(hid, lv); this.heroHistoryCe.set(hid, historyCe); this.heroObjectId.set(hid, objectId); for(let cell of attrs) { let obj = this.getHeroAttrByHidAndId(hid, cell.attrId); obj.setByRoleCe(cell); } } for(let { hid, eplaceId, lv, attrs } of roleCe.equipAttrs) { this.equipLv.set(`${hid}_${eplaceId}`, lv); for(let cell of attrs) { let obj = this.getEquipAttrByHidAndId(hid, eplaceId, cell.attrId); obj.setByRoleCe(cell); } } for(let { hid, attrId, value } of roleCe.schoolAttrs) { this.setSchoolAttrs(hid, attrId, value); } for(let { hid, attrId, value } of roleCe.scrollAttrs) { this.setScrollAttrs(hid, attrId, value); } } } 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 clearRoleAttr(field: string) { for(let globalAttr of this.globalAttrs) { globalAttr[field] = 0; } } public getHeroAttrsByHid(hid: number) { let keys = this.heroAttrsByHid.get(hid)||[]; return keys.map(key => this.heroAttrs.get(key)); } 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 clearHeroAttrByHid(hid: number, field: string) { let heroAttrs = this.getHeroAttrsByHid(hid)||[]; for(let heroAttr of heroAttrs) { heroAttr[field] = 0; } } public getEquipAttrByHidAndId(hid: number, eplaceId: number, attrId: number) { let key = `${hid}_${eplaceId}_${attrId}`; if(!this.equipAttrs.has(key)) { if(ABI_TYPE_MAIN.indexOf(attrId) != -1) { let obj = new EquipMainAttr(hid, attrId); this.equipAttrs.set(key, obj); } else { let obj = new EquipSubAttr(hid, attrId); this.equipAttrs.set(key, obj); } if(!this.equipAttrsByHid.has(hid)) { this.equipAttrsByHid.set(hid, []); } this.equipAttrsByHid.get(hid).push(key); let key2 = `${hid}_${eplaceId}`; if(!this.equipAttrsByHidAndEplace.has(key2)) { this.equipAttrsByHidAndEplace.set(key2, { hid, eplaceId, keys: []}); } this.equipAttrsByHidAndEplace.get(key2).keys.push(key); } return this.equipAttrs.get(key); } public getEquipAttrsByHid(hid: number) { let keys = this.equipAttrsByHid.get(hid)||[]; return keys.map(key => this.equipAttrs.get(key)); } public getEquipAttrsByHidAndEplace(hid: number, eplaceId: number) { let key2 = `${hid}_${eplaceId}`; if(!this.equipAttrsByHidAndEplace.has(key2)) return [] let { keys } = this.equipAttrsByHidAndEplace.get(key2); return keys.map(key => this.equipAttrs.get(key)); } public clearEquipAttrByHidAndEplace(hid: number, eplaceId: number, field: string) { let equipAttrs = this.getEquipAttrsByHidAndEplace(hid, eplaceId); for(let equipAttr of equipAttrs) { equipAttr[field] = 0; } } public clearEquipAttrByHid(hid: number, field: string) { let equipAttrs = this.getEquipAttrsByHid(hid); for(let equipAttr of equipAttrs) { equipAttr[field] = 0; } } public setSchoolAttrs(hid: number, attrId: number, value: number) { let key = `${hid}_${attrId}`; if(!this.schoolAttrs.has(key)) { this.schoolAttrs.set(key, { hid, attrId, ce: value }); if(!this.schoolAttrsByAttrId.has(attrId)) { this.schoolAttrsByAttrId.set(attrId, []); } this.schoolAttrsByAttrId.get(attrId).push(key); if(!this.schoolAttrsByHid.has(hid)) { this.schoolAttrsByHid.set(hid, []); } this.schoolAttrsByHid.get(hid).push(key); } else { this.schoolAttrs.get(key).ce = value; } } public getSchoolAttrsByHid(hid: number) { let keys = this.schoolAttrsByHid.get(hid)||[]; return keys.map(key => this.schoolAttrs.get(key)); } public calSchoolAttrsToGlobal(attrId: number) { let keys = this.schoolAttrsByAttrId.get(attrId)||[]; let schoolResult = 0; for(let key of keys) { let { ce } = this.schoolAttrs.get(key); schoolResult += ce; } let globalAttr = this.getGlobalAttrById(attrId); globalAttr.school = schoolResult; } public clearSchoolAttr(hid: number) { let schoolAttrs = this.getSchoolAttrsByHid(hid)||[]; for(let schoolAttr of schoolAttrs) { schoolAttr.ce = 0; this.calSchoolAttrsToGlobal(schoolAttr.attrId); } } public setScrollAttrs(hid: number, attrId: number, value: number) { let key = `${hid}_${attrId}`; if(!this.scrollAttrs.has(key)) { this.scrollAttrs.set(key, { hid, attrId, ce: value }); if(!this.scrollAttrsByAttrId.has(attrId)) { this.scrollAttrsByAttrId.set(attrId, []); } this.scrollAttrsByAttrId.get(attrId).push(key); if(!this.scrollAttrsByHid.has(hid)) { this.scrollAttrsByHid.set(hid, []); } this.scrollAttrsByHid.get(hid).push(key); } else { this.scrollAttrs.get(key).ce = value; } } public calScrollAttrsToGlobal(attrId: number) { let keys = this.scrollAttrsByAttrId.get(attrId)||[]; let result = 0; for(let key of keys) { let { ce } = this.scrollAttrs.get(key); result += ce; } let globalAttr = this.getGlobalAttrById(attrId); globalAttr.scroll = result; } public clearScrollAttr(hid: number) { let scrollAttrs = this.getScrollAttrsByHid(hid); for(let scrollAttr of scrollAttrs) { scrollAttr.ce = 0; this.calScrollAttrsToGlobal(scrollAttr.attrId); } } public getScrollAttrsByHid(hid: number) { let keys = this.scrollAttrsByHid.get(hid)||[]; return keys.map(key => this.scrollAttrs.get(key)); } public setHistoryCe(hid: number, ce: number) { let historyCe = this.heroHistoryCe.get(hid)||0; if(ce > historyCe) { this.heroHistoryCe.set(hid, ce); } } public setResultHero(hero: HeroType) { this.heroObjectId.set(hero.hid, hero._id); } public getRoleCeTable(roleId: string, attributes: Attribute[]) { let globalAttrs: AttrCell[] = []; 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 historyCe = this.heroHistoryCe.get(hid)||0; let objectId = this.heroObjectId.get(hid); let attrs: AttrCell[] = []; for(let key of keys) { let heroAttr = this.heroAttrs.get(key); attrs.push(heroAttr.getHeroAttrCell()); } heroAttrs.push({ hid, lv, attrs, historyCe, objectId }); } let equipAttrs: EquipAttr[] = []; for(let [key2, { hid, eplaceId, keys }] of this.equipAttrsByHidAndEplace) { let lv = this.equipLv.get(key2); let attrs: AttrCell[] = []; for(let key of keys) { let equipAttr = this.equipAttrs.get(key); attrs.push(equipAttr.getEquipAttrCell()); } equipAttrs.push({ hid, eplaceId, lv, attrs }); } let schoolAttrs: SchoolAttr[] = []; for(let [_, { hid, attrId, ce }] of this.schoolAttrs) { schoolAttrs.push({ hid, attrId, value: ce }); } let scrollAttrs: ScrollAttr[] = []; for(let [_, { hid, attrId, ce }] of this.scrollAttrs) { scrollAttrs.push({ hid, attrId, value: ce }); } return { roleLv: this.roleLv, roleId, globalAttrs, heroAttrs, equipAttrs, schoolAttrs, scrollAttrs, attributes } } } abstract class GlobalAllAttr { attrId: number; school: number = 0; teraph: number = 0; title: number = 0; scroll: number = 0; skin: number = 0; constructor(attrId: number) { this.attrId = attrId; } abstract setByRoleCe(data: AttrCell): void; abstract getValues(): number[]; public getGlobalAttr() { let values = this.getValues().map(cur => (cur||0)); return { attrId: this.attrId, values } } } class GlobalMainAttr extends GlobalAllAttr { public setByRoleCe(globalAttr: AttrCell) { for(let i = 0; i < globalAttr.values.length; i++) { let value = globalAttr.values[i]; if(value != undefined) { switch(i) { case GLOBAL_MAIN_ATTR_INDEX.SCHOOL: this.school = value; break; case GLOBAL_MAIN_ATTR_INDEX.TERAPH: this.teraph = value; break; case GLOBAL_MAIN_ATTR_INDEX.TITLE: this.title = value; break; case GLOBAL_MAIN_ATTR_INDEX.SCROLL: this.scroll = value; break; case GLOBAL_MAIN_ATTR_INDEX.SKIN: this.skin = value; break; } } } } public getValues() { let values: number[] = []; for(let i = GLOBAL_MAIN_ATTR_INDEX.START; i < GLOBAL_MAIN_ATTR_INDEX.END; i++) { switch(i) { case GLOBAL_MAIN_ATTR_INDEX.SCHOOL: values.push(this.school); break; case GLOBAL_MAIN_ATTR_INDEX.TERAPH: values.push(this.teraph); break; case GLOBAL_MAIN_ATTR_INDEX.TITLE: values.push(this.title); break; case GLOBAL_MAIN_ATTR_INDEX.SCROLL: values.push(this.scroll); break; case GLOBAL_MAIN_ATTR_INDEX.SKIN: values.push(this.skin); break; } } return values; } } class GlobalSubAttr extends GlobalAllAttr { public setByRoleCe(globalAttr: AttrCell) { for(let i = 0; i < globalAttr.values.length; i++) { let value = globalAttr.values[i]; if(value != undefined) { switch(i) { case GLOBAL_SUB_ATTR_INDEX.SCHOOL: this.school = value; break; case GLOBAL_MAIN_ATTR_INDEX.TERAPH: this.teraph = value; break; case GLOBAL_MAIN_ATTR_INDEX.TITLE: this.title = value; break; case GLOBAL_MAIN_ATTR_INDEX.SKIN: this.skin = value; break; } } } } public getValues() { let values: number[] = []; for(let i = GLOBAL_MAIN_ATTR_INDEX.START; i < GLOBAL_MAIN_ATTR_INDEX.END; i++) { switch(i) { case GLOBAL_MAIN_ATTR_INDEX.SCHOOL: values.push(this.school); break; case GLOBAL_MAIN_ATTR_INDEX.TERAPH: values.push(this.teraph); break; case GLOBAL_MAIN_ATTR_INDEX.TITLE: values.push(this.title); break; case GLOBAL_MAIN_ATTR_INDEX.SKIN: values.push(this.skin); break; } } return values; } } abstract class HeroAllAttr { hid: number; attrId: number; mainBase: number = 0; // hp1,武将基础属性(dic_zyz_hero的hp) subBase: number = 0; // attr1,职业基础(dic_zyz_job的baseSubAttr字段) job: number = 0; // hp1 & attr2, 职业属性(dic_zyz_job的attr) starUp: number = 0; // hp2, 角色升星成长(dic_zyz_hero_star的hp或dic_zyz_hero_wake的hp) connect: number = 0; // hp3, 角色羁绊固定值(dic_zyz_friend_ship的attribute) favour: number = 0; // 删除-hp4, 声望加成(dic_zyz_friend_ship_level的add) talent: number = 0; // hp5 & attr3, 天赋树百分比加成(dic_zyz_hero_talent的levelSeid,然后对应到dic_zyz_se) equipQuality: number = 0; // hp6, 装备品质基础值(dic_zyz_equipQuality的attribute) equipStrength: number = 0; // hp7, 装备强化值(dic_zyz_equipStrenthAttr的attr) equipStar: number = 0; // hp8 & attr9,装备升星(dic_zyz_equipStar的mainAttr和subAttr) equipSuit: number = 0; // hp8,套装(dic_zyz_equipSuit的effect,然后对应dic_zyz_se) jewel: number = 0; // hp9 & attr7,天晶随机属性值(jewel的ranSe,对应dic_zyz_randomEffectPool) stone: number = 0; // hp10, 地玉增加的固定值(dic_zyz_stone的attribute) constructor(hid: number, attrId: number, ) { this.hid = hid; this.attrId = attrId; } abstract setByRoleCe(data: AttrCell): void; abstract getValues(): number[]; public getHeroAttrCell() { return { attrId: this.attrId, values: this.getValues() } } } class HeroMainAttr extends HeroAllAttr { public setByRoleCe(heroAttr: AttrCell) { for(let i = 0; i < heroAttr.values.length; i++) { let value = heroAttr.values[i]; if(value != undefined) { switch(i) { case HERO_MAIN_ATTR_INDEX.BASE: this.mainBase = value; break; case HERO_MAIN_ATTR_INDEX.JOB: this.job = value; break; case HERO_MAIN_ATTR_INDEX.STAR_UP: this.starUp = value; break; case HERO_MAIN_ATTR_INDEX.CONNECT: this.connect = value; break; case HERO_MAIN_ATTR_INDEX.FAVOUR: this.favour = value; break; case HERO_MAIN_ATTR_INDEX.TALENT: this.talent = value; break; case HERO_MAIN_ATTR_INDEX.EQUIP_QUALITY: this.equipQuality = value; break; case HERO_MAIN_ATTR_INDEX.EQUIP_STRENGTH: this.equipStrength = value; break; case HERO_MAIN_ATTR_INDEX.EQUIP_STAR: this.equipStar = value; break; case HERO_MAIN_ATTR_INDEX.EQUIP_SUIT: this.equipSuit = value; break; case HERO_MAIN_ATTR_INDEX.JEWEL: this.jewel = value; break; case HERO_MAIN_ATTR_INDEX.STONE: this.stone = value; break; } } } } public getValues() { let values: number[] = []; for(let i = HERO_MAIN_ATTR_INDEX.START; i < HERO_MAIN_ATTR_INDEX.END; i++) { switch(i) { case HERO_MAIN_ATTR_INDEX.BASE: values.push(this.mainBase); break; case HERO_MAIN_ATTR_INDEX.JOB: values.push(this.job); break; case HERO_MAIN_ATTR_INDEX.STAR_UP: values.push(this.starUp); break; case HERO_MAIN_ATTR_INDEX.CONNECT: values.push(this.connect); break; case HERO_MAIN_ATTR_INDEX.FAVOUR: values.push(this.favour); break; case HERO_MAIN_ATTR_INDEX.TALENT: values.push(this.talent); break; case HERO_MAIN_ATTR_INDEX.EQUIP_QUALITY: values.push(this.equipQuality); break; case HERO_MAIN_ATTR_INDEX.EQUIP_STRENGTH: values.push(this.equipStrength); break; case HERO_MAIN_ATTR_INDEX.EQUIP_STAR: values.push(this.equipStar); break; case HERO_MAIN_ATTR_INDEX.EQUIP_SUIT: values.push(this.equipSuit); break; case HERO_MAIN_ATTR_INDEX.JEWEL: values.push(this.jewel); break; case HERO_MAIN_ATTR_INDEX.STONE: values.push(this.stone); break; } } return values; } } class HeroSubAttr extends HeroAllAttr { public setByRoleCe(heroAttr: AttrCell) { for(let i = 0; i < heroAttr.values.length; i++) { let value = heroAttr.values[i]; if(value != undefined) { switch(i) { case HERO_SUB_ATTR_INDEX.BASE: this.subBase = value; break; case HERO_SUB_ATTR_INDEX.JOB: this.job = value; break; case HERO_SUB_ATTR_INDEX.TALENT: this.talent = value; break; case HERO_SUB_ATTR_INDEX.JEWEL: this.jewel = value; break; case HERO_SUB_ATTR_INDEX.EQUIP_STAR: this.equipStar = value; break; } } } } public getValues() { let values: number[] = []; for(let i = HERO_SUB_ATTR_INDEX.START; i < HERO_SUB_ATTR_INDEX.END; i++) { switch(i) { case HERO_SUB_ATTR_INDEX.BASE: values.push(this.subBase); break; case HERO_SUB_ATTR_INDEX.JOB: values.push(this.job); break; case HERO_SUB_ATTR_INDEX.TALENT: values.push(this.talent); break; case HERO_SUB_ATTR_INDEX.JEWEL: values.push(this.jewel); break; case HERO_SUB_ATTR_INDEX.EQUIP_STAR: values.push(this.equipStar); break; } } return values; } } abstract class EquipAllAttr { hid: number; eplaceId: number; attrId: number; equipQuality: number = 0; equipStrength: number = 0; equipStar: number = 0; jewel: number = 0; stone: number = 0; constructor(hid: number, attrId: number) { this.hid = hid; this.attrId = attrId; } abstract setByRoleCe(data: AttrCell): void; abstract getValues(): number[]; public getEquipAttrCell() { return { attrId: this.attrId, values: this.getValues() } } } class EquipMainAttr extends EquipAllAttr { public setByRoleCe(equipAttr: AttrCell) { for(let i = 0; i < equipAttr.values.length; i++) { let value = equipAttr.values[i]; if(value != undefined) { switch(i) { case EQUIP_MAIN_ATTR_INDEX.EQUIP_QUALITY: this.equipQuality = value; break; case EQUIP_MAIN_ATTR_INDEX.EQUIP_STRENGTH: this.equipStrength = value; break; case EQUIP_MAIN_ATTR_INDEX.EQUIP_STAR: this.equipStar = value; break; case EQUIP_MAIN_ATTR_INDEX.JEWEL: this.jewel = value; break; case EQUIP_MAIN_ATTR_INDEX.STONE: this.stone = value; break; } } } } public getValues() { let values: number[] = []; for(let i = EQUIP_MAIN_ATTR_INDEX.START; i < EQUIP_MAIN_ATTR_INDEX.END; i++) { switch(i) { case EQUIP_MAIN_ATTR_INDEX.EQUIP_QUALITY: values.push(this.equipQuality); break; case EQUIP_MAIN_ATTR_INDEX.EQUIP_STRENGTH: values.push(this.equipStrength); break; case EQUIP_MAIN_ATTR_INDEX.EQUIP_STAR: values.push(this.equipStar); break; case EQUIP_MAIN_ATTR_INDEX.JEWEL: values.push(this.jewel); break; case EQUIP_MAIN_ATTR_INDEX.STONE: values.push(this.stone); break; } } return values; } } class EquipSubAttr extends EquipAllAttr { public setByRoleCe(equipAttr: AttrCell) { for(let i = 0; i < equipAttr.values.length; i++) { let value = equipAttr.values[i]; if(value != undefined) { switch(i) { case EQUIP_SUB_ATTR_INDEX.EQUIP_STAR: this.equipStar = value; break; case EQUIP_SUB_ATTR_INDEX.JEWEL: this.jewel = value; break; } } } } public getValues() { let values: number[] = []; for(let i = EQUIP_SUB_ATTR_INDEX.START; i < EQUIP_SUB_ATTR_INDEX.END; i++) { switch(i) { case EQUIP_SUB_ATTR_INDEX.EQUIP_STAR: values.push(this.equipStar); break; case EQUIP_SUB_ATTR_INDEX.JEWEL: values.push(this.jewel); break; } } return values; } } enum GLOBAL_MAIN_ATTR_INDEX { START, SCHOOL = 0, // hp5,百家学宫百分比加成(dic_zyz_schoolRate的mainAttrApercent) TERAPH = 1, // hp11, 神像加成(直接读数据库teraph字段的值) TITLE = 2, // hp11, 爵位加成(dic_zyz_title的hp) SCROLL = 3, // hp11,名将谱加成(dic_zyz_heroScroll的hp) SKIN = 4, // hp12, 皮肤加成(dic_zyz_fashion的actorAttr) END } enum GLOBAL_SUB_ATTR_INDEX { START, SCHOOL = 0, // attr5, 百家学宫(根据dic_zyz_school中的upAttribute决定书院加的是那些次级属性,具体值读取dic_zyz_schoolRate中的assiAttrAddValue一列) TERAPH = 1, // attr4, 神像加成(dic_zyz_teraph中的assistAttrValue) TITLE = 2, // attr6, 爵位(dic_zyz_title中的pdi、mdi) SKIN = 3, // attr8, 皮肤 END } enum HERO_MAIN_ATTR_INDEX { START, BASE = 0, // hp1, 角色基础属性(dic_zyz_hero的hp) JOB = 1, // hp1, 职业属性(dic_zyz_job的attr) STAR_UP = 2, // hp2, 角色升星成长(dic_zyz_hero_star的hp或dic_zyz_hero_wake的hp) CONNECT = 3, // hp3, 角色羁绊固定值(dic_zyz_friend_ship的attribute) FAVOUR = 4, // hp4, 声望加成(dic_zyz_friend_ship_level的add) TALENT = 5, // hp5, 天赋树百分比加成(dic_zyz_hero_talent的levelSeid,然后对应到dic_zyz_se) EQUIP_QUALITY = 6, // hp6, 装备品质基础值(dic_zyz_equipQuality的attribute) EQUIP_STRENGTH = 7, // hp7, 装备强化值(dic_zyz_equipStrenthAttr的attr) EQUIP_STAR = 8, // hp8,装备升星(dic_zyz_equipStar的mainAttr) EQUIP_SUIT = 9, // hp8,套装(dic_zyz_equipSuit的effect,然后对应dic_zyz_se) JEWEL = 10, // hp9,天晶随机属性值(jewel的ranSe,对应dic_zyz_randomEffectPool) STONE = 11, // hp10, 地玉增加的固定值(dic_zyz_stone的attribute) END } enum HERO_SUB_ATTR_INDEX { START, BASE = 0, // attr1,系统参数表中所有人 JOB = 1, // attr2, 职业的attr TALENT = 2, // attr3, 天赋树百分比加成 (dic_zyz_hero_talent的levelSeid,然后对应到dic_zyz_se) JEWEL = 3, // attr7, 天晶随机属性(随机出来的值在dic_zyz_randomEffectPool中读最终值) EQUIP_STAR = 4, // attr9, 精炼次级属性(dic_zyz_equipStar的subAttr) END } enum EQUIP_MAIN_ATTR_INDEX { START, EQUIP_QUALITY = 0, // hp6, 装备升品基础值加成(dic_zyz_equipQuality) EQUIP_STRENGTH = 1,// hp7, 装备强化值(需改表,改为键值对) EQUIP_STAR = 2, // hp8, 装备(dic_zyz_equipStar) JEWEL = 3, // hp9, 天晶洗练出的主属性百分比加成,equipAttr加起来 STONE = 4, // hp10,地玉石增加的固定值,equipAttr加起来 END } enum EQUIP_SUB_ATTR_INDEX { START, JEWEL = 0, // attr7, 天晶随机属性(随机出来的值在dic_zyz_randomEffectPool中读最终值) EQUIP_STAR = 1, // attr9, 精炼次级属性(dic_zyz_equipStar的subAttr) END }