创建武将

This commit is contained in:
陆莹
2022-03-25 14:14:36 +08:00
parent a394bae03e
commit 1bdace30f9
17 changed files with 747 additions and 357 deletions
+465
View 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
}