创建武将
This commit is contained in:
@@ -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
|
||||
}
|
||||
Reference in New Issue
Block a user