Files
ZYZ/shared/pubUtils/itemUtils.ts
2021-08-05 13:42:21 +08:00

386 lines
16 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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 { randMin, randMax } = getQuenchByQualityAndGrade(quality, grade);
let rand = getRandValueByMinMax(randMin, randMax, 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 }
}