373 lines
14 KiB
TypeScript
373 lines
14 KiB
TypeScript
|
||
|
||
import { HeroModel, HeroType, } from '../db/Hero';
|
||
import { ItemModel } from '../db/Item';
|
||
import { gameData } from './data';
|
||
import { ITID, CURRENCY_BY_TYPE, CURRENCY_TYPE, ROLE_SELECT, FIGURE_UNLOCK_CONDITION, CONSUME_TYPE, HERO_SYSTEM_TYPE, ITEM_CHANGE_REASON } from '../consts';
|
||
import { getRandValueByMinMax, getRandEelm, getRandEelmWithWeight, getDecimalCnt } from './util';
|
||
|
||
import { findWhere } from 'underscore';
|
||
import { RoleModel, RoleType, } from '../db/Role';
|
||
import { Figure } from '../domain/dbGeneral';
|
||
import { getTimeFun } from './timeUtil';
|
||
import { reCalAllHeroCe } from './playerCe';
|
||
// import { checkTask, checkTaskWithHeroes, checkTaskWithEquip, accomplishTask } from './taskUtil';
|
||
import { SkinModel, } from '../db/Skin';
|
||
import { TaskListReturn } from '../domain/roleField/task';
|
||
import { JewelModel, jewelUpdate, RandSe, } from '../db/Jewel';
|
||
|
||
/**
|
||
* 只插入皮肤,不管那么多的
|
||
* @param roleId
|
||
* @param roleName
|
||
* @param skinId
|
||
* @returns
|
||
*/
|
||
export async function increaseSkin(roleId:string, roleName: string, skinId: number) {
|
||
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, skinId: dicSkin.heroId });
|
||
if(!skin) return false; // 插入失败
|
||
return skin
|
||
}
|
||
|
||
/**
|
||
* 添加皮肤
|
||
* @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 skin = await increaseSkin(roleId, roleName, skinId);
|
||
if(!skin) return false;
|
||
|
||
if(skin.hid && !hero) hero = await HeroModel.findByHidAndRole(skin.hid, 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, skinId: skin.skinId });
|
||
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 }[], reason: number) {
|
||
let items: { id: number, count: number, inc: number }[] = [];
|
||
for(let data of datas) {
|
||
let item = await addBag(roleId, roleName, data, reason);
|
||
items.push(item)
|
||
}
|
||
return { items }
|
||
}
|
||
|
||
export async function addBag(roleId: string, roleName: string, data: { id: number, count: number }, reason: 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, inc: count, reason };
|
||
}
|
||
|
||
|
||
export async function addJewels(roleId: string, roleName: string, jewels: { id: number, }[], reason: number) {
|
||
let jewelInfo: jewelUpdate[] = [];
|
||
for(let jewel of jewels) {
|
||
let info = await getAddJewelInfo(roleId, roleName, jewel);
|
||
jewelInfo.push(info);
|
||
}
|
||
|
||
const jewelResult = await JewelModel.createJewels(roleId, jewelInfo);
|
||
let pushMessages: TaskListReturn[] = [];
|
||
// TODO 修改任务
|
||
// for(let equip of jewelResult) {
|
||
// let pushMessage = await checkTaskWithEquip(roleId, TASK_TYPE.EQUIP_SUIT, equip);
|
||
// if(reason == ITEM_CHANGE_REASON.EQUIP_COMPOSE) {
|
||
// let pm = await checkTaskWithEquip(roleId, TASK_TYPE.EQUIP_COMPOSE_SUIT, equip);
|
||
// pushMessages.push(...pm);
|
||
// }
|
||
// pushMessages.push(...pushMessage);
|
||
// }
|
||
|
||
return { jewels: jewelResult.map(jewel => {
|
||
return { ...jewel, count: 1, inc: 1, reason }
|
||
}), pushMessages }
|
||
}
|
||
|
||
export async function getAddJewelInfo(roleId: string, roleName: string, jewel: { id: number, }) {
|
||
let { id, } = jewel;
|
||
let { name, randomEffect, effectCount } = gameData.jewel.get(id);
|
||
|
||
// 随机属性
|
||
let randomResult: number[] = getRandEelm(randomEffect, effectCount);
|
||
|
||
let randSe: Array<RandSe> = randomResult.map((id: number, index: number) => {
|
||
return getJewelRandSe(index + 1, id);
|
||
});
|
||
|
||
return { roleId, roleName, id, name, randSe };
|
||
}
|
||
|
||
/**
|
||
* 天晶石已知词条随机值
|
||
* @param id 词条位置,第几条
|
||
* @param seid 词条id
|
||
* @returns
|
||
*/
|
||
export function getJewelRandSe(id: number, seid: number) {
|
||
let dicRandom = gameData.randomEffectPool.get(seid)
|
||
let rand = 0;
|
||
if (dicRandom.id > 0) {
|
||
let randRange = getRandEelmWithWeight(dicRandom.rate);
|
||
let randResult = getRandValueByMinMax(randRange.dic.min, randRange.dic.max, getDecimalCnt(dicRandom.gap));
|
||
let n = Math.floor((randResult - dicRandom.Min)/dicRandom.gap);
|
||
rand = dicRandom.Min + n * dicRandom.gap;
|
||
}
|
||
return new RandSe(id, dicRandom.id, rand);
|
||
}
|
||
|
||
/**
|
||
* @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 getApObject(count: number) {
|
||
return { id: CURRENCY_BY_TYPE.get(CURRENCY_TYPE.ACTION_POINT), 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 conditions 解锁条件
|
||
* @param role 如果已查询过role表就直接可以使用
|
||
*/
|
||
export function unlockFigureWithoutSave(conditions: { type: number, paramHid?: number, paramFavourLv?: number, paramSkinId?: number, paramWinStreakNum?: number }[], role: RoleType) {
|
||
|
||
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, paramWinStreakNum } of conditions) {
|
||
let canUnLockList = gameData.figureCondition.get(type);
|
||
if (canUnLockList) {
|
||
let reason = 0;
|
||
|
||
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;
|
||
reason = ITEM_CHANGE_REASON.GET_HERO_UNLOCK_FIGURE;
|
||
} else if (type == FIGURE_UNLOCK_CONDITION.HERO_FAVOR) {
|
||
let [hid, favourLv] = params;
|
||
if (paramHid == hid && paramFavourLv >= favourLv) flag = true;
|
||
reason = ITEM_CHANGE_REASON.HERO_FAVOR_UNLOCK_FIGURE;
|
||
} else if (type == FIGURE_UNLOCK_CONDITION.GET_SKIN) {
|
||
let [id] = params;
|
||
if (paramSkinId == id) flag = true;
|
||
reason = ITEM_CHANGE_REASON.ADD_SKIN_UNLOCK_FIGURE;
|
||
} else if (type == FIGURE_UNLOCK_CONDITION.PVP_WIN_SERIES) {
|
||
let [winStreakNum] = params;
|
||
if (paramWinStreakNum >= winStreakNum) flag = true;
|
||
reason = ITEM_CHANGE_REASON.PVP_SERIES_UNLOCK_FIGURE;
|
||
}
|
||
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, reason, false, id);
|
||
if (figure && figure.unlocked) figureInfo.heads.push(figure);
|
||
} else if (dicItid.type == CONSUME_TYPE.FRAME) {
|
||
let figure = unlockSingleFigure(frames, gid, reason, false, id);
|
||
if (figure && figure.unlocked) figureInfo.frames.push(figure);
|
||
} else if (dicItid.type == CONSUME_TYPE.SPINE) {
|
||
let figure = unlockSingleFigure(spines, gid, reason, false, id);
|
||
if (figure && figure.unlocked) figureInfo.spines.push(figure);
|
||
} else {
|
||
continue;
|
||
}
|
||
|
||
}
|
||
|
||
}
|
||
}
|
||
return { figureInfo, heads, frames, spines };
|
||
}
|
||
|
||
/**
|
||
* 解锁头像/相框
|
||
* @param roleId 玩家id
|
||
* @param conditions 解锁条件
|
||
* @param role 如果已查询过role表就直接可以使用
|
||
*/
|
||
export async function unlockFigure(roleId: string, conditions: { type: number, paramHid?: number, paramFavourLv?: number, paramSkinId?: number, paramWinStreakNum?: number }[], role?: RoleType) {
|
||
if (!role || !role.heads || !role.frames) {
|
||
role = await RoleModel.findByRoleId(roleId, ROLE_SELECT.GET_HEADS);
|
||
}
|
||
let { figureInfo, heads, frames, spines } = unlockFigureWithoutSave(conditions, role);
|
||
role = await RoleModel.updateRoleInfo(roleId, { heads, frames, spines });
|
||
return figureInfo;
|
||
}
|
||
|
||
|
||
// 直接获得形象/相框
|
||
export async function addFigure(roleId: string, ids: number[], reason: 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, reason, true);
|
||
if (figure && figure.unlocked) figureInfo.heads.push(figure);
|
||
} else if (dicItid.type == CONSUME_TYPE.FRAME) {
|
||
let figure = unlockSingleFigure(frames, gid, reason, true);
|
||
if (figure && figure.unlocked) figureInfo.frames.push(figure);
|
||
} else if (dicItid.type == CONSUME_TYPE.SPINE) {
|
||
let figure = unlockSingleFigure(spines, gid, reason, 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, reason: number, unlockDirect = false, conditionId?: number) {
|
||
let index = dbFigures.findIndex(cur => cur.id == id);
|
||
let figure = dbFigures[index];
|
||
if (index == -1) {
|
||
figure = new Figure(id, false);
|
||
dbFigures.push(figure);
|
||
index = dbFigures.length - 1;
|
||
}
|
||
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天以后
|
||
}
|
||
}
|
||
|
||
figure.inc = 1;
|
||
figure.reason = reason;
|
||
dbFigures[index] = figure;
|
||
return figure
|
||
}
|
||
|
||
// async function getSkinsOfThisHero(roleId: string, roleName: string, hid: number, initialSkin: number, allSkins?: SkinType[]) {
|
||
// if(!allSkins) allSkins = await SkinModel.findbyRoleAndHid(roleId, hid);
|
||
// let skin = await increaseSkin(roleId, roleName, initialSkin);
|
||
// if(skin) allSkins.push(skin);
|
||
// let skins: { id: number, skin: string, enable: boolean }[] = [];
|
||
// for(let skin of allSkins) {
|
||
// skins.push({ id: skin.id, skin: skin._id, enable: skin.id == initialSkin });
|
||
// }
|
||
|
||
// return skins
|
||
// }
|
||
|
||
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 }
|
||
}
|
||
|
||
// export class CreateHero {
|
||
// roleId: string;
|
||
// roleName: string;
|
||
// serverId: number;
|
||
|
||
// constructor(roleId: string, roleName: string, serverId: number) {
|
||
|
||
// }
|
||
// }
|