386 lines
16 KiB
TypeScript
386 lines
16 KiB
TypeScript
|
|
|
|
import { HeroModel, HeroType } from '../db/Hero';
|
|
import { ItemModel } from '../db/Item';
|
|
import { EquipModel, RandSe, Holes, RandMain, equipUpdate } from './../db/Equip';
|
|
import { gameData, getQuenchByQualityAndGrade, getQuenchGradeByValue } from './data';
|
|
import { RANDOM_SE_COUNT, ITID, CURRENCY_BY_TYPE, CURRENCY_TYPE, ROLE_SELECT, FIGURE_UNLOCK_CONDITION, CONSUME_TYPE, HERO_SYSTEM_TYPE, TASK_TYPE } from '../consts';
|
|
import { getRandValueByMinMax, getRandEelm } from './util';
|
|
|
|
import { findWhere } from 'underscore';
|
|
import { RoleModel, RoleType } from '../db/Role';
|
|
import { Figure } from '../domain/dbGeneral';
|
|
import { getTimeFun, nowSeconds } from './timeUtil';
|
|
import { calPlayerCeAndSave, reCalAllHeroCe } from './playerCe';
|
|
import { checkTask, checkTaskWithHeroes, checkTaskWithEquip, accomplishTask } from './taskUtil';
|
|
import { CreateHeroParam } from '../domain/roleField/hero';
|
|
import { SkinModel } from '../db/Skin';
|
|
import { TaskListReturn } from '../domain/roleField/task';
|
|
|
|
/**
|
|
* 添加皮肤
|
|
* @param roleId 玩家id
|
|
* @param roleName 玩家名
|
|
* @param id 皮肤id
|
|
* @param hero 武将,如果已经查询过这个武将就不用再查询一次,主意要select skins字段
|
|
* @returns {{ hero, figureInfo, calAllHeroResult }} hero:添加皮肤后的武将 figureInfo: 触发头像添加信息 calAllHeroResult:全局战力加成后结果
|
|
*/
|
|
export async function addSkin(roleId: string, roleName: string, skinId: number, enable: boolean, hero?: HeroType) {
|
|
let dicSkin = gameData.fashion.get(skinId);
|
|
if (!dicSkin) return false;
|
|
|
|
let skin = await SkinModel.increaseSkin(roleId, skinId, { roleId, roleName, id: skinId, skinName: dicSkin.name, hid: dicSkin.actorId });
|
|
if(!skin) return false; // 插入失败
|
|
|
|
if(dicSkin.actorId && !hero) hero = await HeroModel.findByHidAndRole(dicSkin.actorId, roleId);
|
|
let condition = { type: FIGURE_UNLOCK_CONDITION.GET_SKIN, paramSkinId: skinId };
|
|
let figureInfo = await unlockFigure(roleId, [condition]); // 解锁头像
|
|
let calAllHeroResult = await reCalAllHeroCe(HERO_SYSTEM_TYPE.ADD_SKIN, roleId, {}, [skinId]); // 全局加成
|
|
|
|
if (hero) { // 有武将的,将皮肤链接到武将上
|
|
if (!findWhere(hero.skins, { id: skinId })) {
|
|
hero.skins.push({ id: skinId, skin: skin._id, enable });
|
|
await HeroModel.updateHeroInfo(roleId, hero.hid, hero);
|
|
}
|
|
return { hero, figureInfo, calAllHeroResult };
|
|
} else {
|
|
return { hero: null, figureInfo, calAllHeroResult }
|
|
}
|
|
}
|
|
|
|
export async function addBags(roleId: string, roleName: string, datas: { id: number, count: number }[]) {
|
|
let items: { id: number, count: number }[] = [];
|
|
for(let data of datas) {
|
|
let item = await addBag(roleId, roleName, data);
|
|
items.push(item)
|
|
}
|
|
return { items }
|
|
}
|
|
|
|
export async function addBag(roleId: string, roleName: string, data: { id: number, count: number }) {
|
|
let { id, count } = data;
|
|
let { name: itemName, itid, hid } = gameData.goods.get(id);
|
|
let { type } = ITID.get(itid);
|
|
|
|
let item = await ItemModel.increaseItem(roleId, id, count, { roleId, roleName, itemName, id, type, hid });
|
|
return { id: item.id, count: item.count };
|
|
}
|
|
|
|
|
|
export async function addEquips(roleId: string, roleName: string, weapons: { id: number, hid?: number }[]) {
|
|
let equipInfos: equipUpdate[] = [];
|
|
for(let weapon of weapons) {
|
|
let info = await getAddEquipInfo(roleId, roleName, weapon);
|
|
equipInfos.push(info);
|
|
}
|
|
|
|
const equips = await EquipModel.createEquips(roleId, equipInfos);
|
|
let pushMessages: TaskListReturn[] = [];
|
|
// 任务
|
|
for(let equip of equips) {
|
|
let pushMessage = await checkTaskWithEquip(roleId, TASK_TYPE.EQUIP_SUIT, equip);
|
|
pushMessages = [...pushMessages, ...pushMessage];
|
|
}
|
|
|
|
return { equips, pushMessages }
|
|
}
|
|
|
|
export async function getAddEquipInfo(roleId: string, roleName: string, weapon: { id: number, hid?: number }) {
|
|
let { id, hid = 0 } = weapon;
|
|
let { name, quality, suitId, hole, randomEffect, itid, goodsAbility } = gameData.goods.get(id);
|
|
let { type } = ITID.get(itid);
|
|
|
|
// 随机属性
|
|
let randomNum = RANDOM_SE_COUNT.get(quality);
|
|
let randomResult: number[] = getRandEelm(randomEffect, randomNum);
|
|
|
|
let randSe: Array<RandSe> = randomResult.map((id: number, i: number) => {
|
|
let random = gameData.randomEffectPool.get(id)
|
|
let rand = 0;
|
|
if (random.id > 0) rand = getRandValueByMinMax(random.Min, random.Max, 0);
|
|
return {
|
|
id: i + 1,
|
|
seid: random.id,
|
|
rand,
|
|
locked: false
|
|
};
|
|
});
|
|
|
|
let randRange = 0;
|
|
|
|
// 淬火品相
|
|
let randMain: RandMain[] = [];
|
|
let grade = 0;
|
|
for(let [ attrId, attrValue ] of goodsAbility) {
|
|
if(attrValue > 0) {
|
|
let { min, max } = getQuenchByQualityAndGrade(quality, grade);
|
|
let rand = getRandValueByMinMax(min, max, 0);
|
|
console.log(quality, grade, rand)
|
|
grade = getQuenchGradeByValue(quality, rand);
|
|
randMain.push({
|
|
id: attrId,
|
|
rand
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
let holes = new Array<Holes>();
|
|
for (let i = 0; i < hole; i++) {
|
|
holes.push({ id: i + 1, isOpen: false, jewel: 0 });
|
|
}
|
|
|
|
return { roleId, roleName, id, name, quality, suitId, randRange, ePlaceId: type, randSe, holes, hid, grade, randMain };
|
|
}
|
|
|
|
/**
|
|
* @description 获取元宝物品 { id, count }
|
|
* @param count 元宝数量
|
|
*/
|
|
export function getGoldObject(count: number) {
|
|
return { id: CURRENCY_BY_TYPE.get(CURRENCY_TYPE.GOLD), count };
|
|
}
|
|
|
|
/**
|
|
* @description 获取金币物品 { id, count }
|
|
* @param count 元宝数量
|
|
*/
|
|
export function getCoinObject(count: number) {
|
|
return { id: CURRENCY_BY_TYPE.get(CURRENCY_TYPE.COIN), count };
|
|
}
|
|
|
|
/**
|
|
* @description 获取友情点物品 { id, count }
|
|
* @param count 友情点数量
|
|
*/
|
|
export function getFriendPointObject(count: number) {
|
|
return { id: CURRENCY_BY_TYPE.get(CURRENCY_TYPE.FRIEND_POINT), count };
|
|
}
|
|
|
|
/**
|
|
* @description 获取功勋物品 { id, count }
|
|
* @param count 功勋数量
|
|
*/
|
|
export function getHonourObject(count: number) {
|
|
return { id: CURRENCY_BY_TYPE.get(CURRENCY_TYPE.HONOUR), count };
|
|
}
|
|
/**
|
|
* 解锁头像/相框
|
|
* @param roleId 玩家id
|
|
* @param conditions 解锁条件
|
|
* @param role 如果已查询过role表就直接可以使用
|
|
*/
|
|
export async function unlockFigure(roleId: string, conditions: { type: number, paramHid?: number, paramFavourLv?: number, paramSkinId?: number }[], role?: RoleType) {
|
|
if (!role || !role.heads || !role.frames) {
|
|
role = await RoleModel.findByRoleId(roleId, ROLE_SELECT.GET_HEADS);
|
|
}
|
|
let { heads, frames, spines } = role;
|
|
let figureInfo = { heads: new Array<Figure>(), frames: new Array<Figure>(), spines: new Array<Figure>() };
|
|
for (let { type, paramHid, paramFavourLv, paramSkinId } of conditions) {
|
|
let canUnLockList = gameData.figureCondition.get(type);
|
|
if (canUnLockList) {
|
|
for (let { id, params, gid } of canUnLockList) {
|
|
let flag = false; // 是否达成条件
|
|
if (type == FIGURE_UNLOCK_CONDITION.GET_HERO) {
|
|
let [hid] = params;
|
|
if (paramHid == hid) flag = true;
|
|
} else if (type == FIGURE_UNLOCK_CONDITION.HERO_FAVOR) {
|
|
let [hid, favourLv] = params;
|
|
if (paramHid == hid && paramFavourLv >= favourLv) flag = true;
|
|
} else if (type == FIGURE_UNLOCK_CONDITION.GET_SKIN) {
|
|
let [id] = params;
|
|
if (paramSkinId == id) flag = true;
|
|
}
|
|
if (!flag) continue;
|
|
let dicGood = gameData.goods.get(gid);
|
|
if (!dicGood) continue;
|
|
let dicItid = ITID.get(dicGood.itid);
|
|
if (!dicItid) continue;
|
|
|
|
if (dicItid.type == CONSUME_TYPE.HEAD) {
|
|
let figure = unlockSingleFigure(heads, gid, false, id);
|
|
if (figure && figure.unlocked) figureInfo.heads.push(figure);
|
|
} else if (dicItid.type == CONSUME_TYPE.FRAME) {
|
|
let figure = unlockSingleFigure(frames, gid, false, id);
|
|
if (figure && figure.unlocked) figureInfo.frames.push(figure);
|
|
} else if (dicItid.type == CONSUME_TYPE.SPINE) {
|
|
let figure = unlockSingleFigure(spines, gid, false, id);
|
|
if (figure && figure.unlocked) figureInfo.spines.push(figure);
|
|
} else {
|
|
continue;
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
}
|
|
role = await RoleModel.updateRoleInfo(roleId, { heads, frames, spines });
|
|
return figureInfo;
|
|
}
|
|
|
|
|
|
// 直接获得形象/相框
|
|
export async function addFigure(roleId: string, ids: number[]) {
|
|
let role = await RoleModel.findByRoleId(roleId, ROLE_SELECT.GET_HEADS);
|
|
|
|
if (!role) return false;
|
|
let { heads, frames, spines } = role;
|
|
|
|
let figureInfo = { heads: [], frames: [], spines: [] };
|
|
for (let gid of ids) {
|
|
let dicGoods = gameData.goods.get(gid);
|
|
if (!dicGoods) continue;
|
|
let dicItid = ITID.get(dicGoods.itid);
|
|
if (!dicItid) continue;
|
|
|
|
if (dicItid.type == CONSUME_TYPE.HEAD) {
|
|
let figure = unlockSingleFigure(heads, gid, true);
|
|
if (figure && figure.unlocked) figureInfo.heads.push(figure);
|
|
} else if (dicItid.type == CONSUME_TYPE.FRAME) {
|
|
let figure = unlockSingleFigure(frames, gid, true);
|
|
if (figure && figure.unlocked) figureInfo.frames.push(figure);
|
|
} else if (dicItid.type == CONSUME_TYPE.SPINE) {
|
|
let figure = unlockSingleFigure(spines, gid, true);
|
|
if (figure && figure.unlocked) figureInfo.spines.push(figure);
|
|
} else {
|
|
continue;
|
|
}
|
|
}
|
|
|
|
role = await RoleModel.updateRoleInfo(roleId, { heads, frames, spines });
|
|
return figureInfo;
|
|
}
|
|
|
|
/**
|
|
* 根据物品id解锁/获得玩家数据
|
|
* @param dbFigures 数据库内字段
|
|
* @param id 物品id
|
|
* @param unlockDirect 是否不计算解锁条件直接解锁
|
|
* @param conditionId 条件id
|
|
*/
|
|
function unlockSingleFigure(dbFigures: Figure[], id: number, unlockDirect = false, conditionId?: number) {
|
|
let figure = dbFigures.find(cur => cur.id == id);
|
|
if (!figure) {
|
|
figure = new Figure(id, false);
|
|
dbFigures.push(figure);
|
|
}
|
|
if (figure.unlocked) return; // 已解锁过
|
|
if (!figure.unlockedId) figure.unlockedId = new Array<number>();
|
|
|
|
let dicGoods = gameData.goods.get(id);
|
|
|
|
let hasUnlockedAll = true;
|
|
if (!unlockDirect) { // 不能直接获得,需要通过type解锁
|
|
if (figure.unlockedId.includes(conditionId)) return;
|
|
|
|
figure.unlockedId.push(conditionId);
|
|
|
|
for (let { id: cid } of dicGoods.condition) {
|
|
if (!figure.unlockedId.includes(cid)) {
|
|
hasUnlockedAll = false; break;
|
|
}
|
|
}
|
|
}
|
|
if (hasUnlockedAll) {
|
|
figure.unlocked = true;
|
|
delete figure.unlockedId;
|
|
|
|
if (dicGoods.timeLimit) {
|
|
figure.time = <number>getTimeFun().getAfterDay(dicGoods.timeLimit); // timeLimit天以后
|
|
}
|
|
}
|
|
|
|
return figure
|
|
}
|
|
|
|
async function linkOldSkins(roleId: string, hero: HeroType) {
|
|
let allSkins = await SkinModel.findbyRoleAndHid(roleId, hero.hid);
|
|
let skins = hero.skins||[];
|
|
for(let skin of allSkins) {
|
|
let index = skins.findIndex(cur => cur.id == skin.id);
|
|
if(index == -1) {
|
|
skins.push({ id: skin.id, skin: skin._id, enable: false });
|
|
}
|
|
}
|
|
return await HeroModel.updateHeroInfo(roleId, hero.hid, { skins })
|
|
}
|
|
|
|
/**
|
|
* 创建武将
|
|
* @param roleId 玩家id
|
|
* @param roleName 玩家名
|
|
* @param serverId 服务器id
|
|
* @param {CreateHeroParam} heroInfo 创建武将所需信息
|
|
* @param funcs 玩家开启了的功能,主要用于任务
|
|
*/
|
|
export async function createHero(roleId: string, roleName: string, serverId: number, heroInfo: CreateHeroParam, funcs?: number[]) {
|
|
let { role, figureInfo, heroes, calHeroResults, calAllHeroResult, taskPushMessage, activityTaskPushMessage } = await createHeroes(roleId, roleName, serverId, [heroInfo], funcs)
|
|
return { hero: heroes[0], role, figureInfo, calHeroResult: calHeroResults[0], calAllHeroResult, taskPushMessage, activityTaskPushMessage }
|
|
}
|
|
|
|
export async function createHeroes(roleId: string, roleName: string, serverId: number, heroInfos: CreateHeroParam[], funcs?: number[]) {
|
|
|
|
let heroNum = 0;
|
|
let conditions = new Array<{ type: number, paramHid?: number, paramFavourLv?: number, paramSkinId?: number }>();
|
|
let heroes: HeroType[] = [], calHeroResults = [], calAllHeroResult = undefined;
|
|
let figureInfos:{ heads: Figure[], frames: Figure[], spines: Figure[] }[] = [];
|
|
|
|
for (let heroInfo of heroInfos) {
|
|
let dicHero = gameData.hero.get(heroInfo.hid);
|
|
let { quality, initialStars: star, jobid: job, name: hName, initialSkin } = dicHero;
|
|
|
|
let info = { roleId, roleName, serverId, quality, star, job, hName };
|
|
|
|
let curHero = await HeroModel.createHero(Object.assign(info, heroInfo));
|
|
let addSkinResult = await addSkin(roleId, roleName, initialSkin, true, curHero); // 添加皮肤
|
|
curHero = await linkOldSkins(roleId, curHero);
|
|
|
|
if(addSkinResult) { // 处理添加皮肤结果
|
|
curHero = addSkinResult.hero;
|
|
figureInfos.push(addSkinResult.figureInfo);
|
|
calAllHeroResult = addSkinResult.calAllHeroResult; // 全局加成,所以同一个人的处理都是累加
|
|
}
|
|
// 计算初始战力
|
|
let calHeroResult = await calPlayerCeAndSave(HERO_SYSTEM_TYPE.INIT, roleId, curHero, {});
|
|
calHeroResults.push(calHeroResult);
|
|
heroes.push(calHeroResult.hero);
|
|
conditions.push({ type: FIGURE_UNLOCK_CONDITION.GET_HERO, paramHid: heroInfo.hid });
|
|
heroNum++;
|
|
}
|
|
figureInfos.push(await unlockFigure(roleId, conditions)); // 解锁头像
|
|
|
|
let role = await RoleModel.incRoleInfo(roleId, { heroNum }, { heroNumUpdatedAt: nowSeconds() });
|
|
// 任务
|
|
let m1 = await checkTask(roleId, TASK_TYPE.HERO_NUM, heroNum, true, {}, funcs);
|
|
let m2 = await checkTaskWithHeroes(roleId, TASK_TYPE.HERO_QUALITY, heroes, funcs);
|
|
let m3 = await checkTaskWithHeroes(roleId, TASK_TYPE.HERO_QUALITY_STAR_UP, heroes, funcs);
|
|
let m4 = await checkTaskWithHeroes(roleId, TASK_TYPE.HERO_LV, heroes, funcs);
|
|
let taskPushMessage = m1.concat(m2, m3, m4);
|
|
//成长任务
|
|
let mm1 = await accomplishTask(serverId, roleId, TASK_TYPE.HERO_NUM, heroNum)
|
|
let mm2 = await accomplishTask(serverId, roleId, TASK_TYPE.HERO_QUALITY, heroNum, { heroes })
|
|
let activityTaskPushMessage = mm1.concat(mm2);
|
|
return { role, figureInfo: combineFigureInfo(figureInfos), heroes, calHeroResults, calAllHeroResult, taskPushMessage, activityTaskPushMessage }
|
|
}
|
|
|
|
export function combineFigureInfo(figureInfos: { heads: Figure[], frames: Figure[], spines: Figure[] }[]) {
|
|
let figureInfo = { heads: new Array<Figure>(), frames: new Array<Figure>(), spines: new Array<Figure>() };
|
|
for(let {heads, frames, spines} of figureInfos) {
|
|
for(let head of heads) {
|
|
figureInfo.heads.push(head);
|
|
}
|
|
for(let frame of frames) {
|
|
figureInfo.frames.push(frame);
|
|
}
|
|
for(let spine of spines) {
|
|
figureInfo.spines.push(spine);
|
|
}
|
|
}
|
|
return figureInfo;
|
|
}
|
|
|
|
export function transPiece(hid: number) {
|
|
let dicHero = gameData.hero.get(hid);
|
|
let count = gameData.heroTransPiece.get(dicHero.quality);
|
|
return { pieceId: dicHero.pieceId, count }
|
|
} |