Files
ZYZ/game-server/app/services/rewardService.ts
2020-12-17 13:17:19 +08:00

300 lines
11 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { GOOD_TYPE, ITID, CURRENCY, CURRENCY_TYPE, COUNTER, CONSUME_TYPE, getCurNameById } from './../consts/consts';
import { EquipModel } from './../db/Equip';
import { CounterModel } from './../db/Counter';
import { decodeStr, resResult } from '../pubUtils/util';
import { getGoodById } from '../pubUtils/gamedata';
import { RoleModel } from '../db/Role';
import { setAp } from './actionPointService';
import { ItemModel } from '../db/Item';
import { STATUS } from '../consts/statusCode';
import { pinus } from 'pinus';
import { addEquips, addBags, addSkins } from '../pubUtils/itemUtils';
const _ = require('underscore');
export async function handleFixedReward(roleId: string, roleName: string, rewardStr: string, multi: number) {
let reward = decodeStr('fixReward', rewardStr);
let rewards = [];
for(let obj of reward)
rewards.push({ ...obj, count: Math.ceil(obj.count * multi)});
const result = await handleReward(roleId, roleName, reward);
return result;
}
export async function handleReward(roleId: string, roleName: string, rewards: Array<{type?: number, gid: number, count: number, times?: number}>) {
let returnGoods = new Array(), getGold = 0, getCoin = 0, getAp = 0;
for(let goods of rewards) {
let goodInfo = getGoodById(goods.gid);
let result = new Array<any>()
if(goodInfo.goodType == GOOD_TYPE.EQUIP) { // 装备
result = await rewardWeapons(roleId, roleName, goodInfo, {id: goods.gid, cnt: goods.count });
} else if(goodInfo.goodType == GOOD_TYPE.CONSUMES|| goodInfo.goodType == GOOD_TYPE.SCRIPT) { // 消耗品
let {type, isCurrency} = ITID.get(goodInfo.itid);
if(isCurrency) { // 货币
result = await rewardCurrency(roleId, goodInfo, {id: goods.gid, cnt: goods.count });
} else {
result = await rewardItems(roleId, roleName, goodInfo, type, {id: goods.gid, cnt: goods.count });
}
}
for(let obj of result) {
returnGoods.push({dropType: goods.type, times: goods.times, ...obj});
if(obj.isCurrency) {
if(obj.currencyType == CURRENCY_TYPE.GOLD) {
getGold += obj.count;
} else if (obj.currencyType == CURRENCY_TYPE.COIN) {
getCoin += obj.count;
} else if (obj.currencyType == CURRENCY_TYPE.ACTION_POINT) {
getAp += obj.count;
}
}
}
}
return {
goods: returnGoods,
getGold,
getCoin,
getAp
};
}
async function rewardWeapons (roleId: string, roleName: string, dicGood: any, weapon: {id:number,cnt:number }) {
let weaponsData = [];
let cnt = weapon.cnt;
while (cnt > 0) {
const seqId = await CounterModel.getNewCounter(COUNTER.EID);
const equipInfo = {
roleId,
roleName,
id: weapon.id,
name: dicGood.name,
seqId,
quality: dicGood.lv,
type: dicGood.goodType
}
const equip = await EquipModel.createEquip(equipInfo);
cnt -= 1;
weaponsData.push(equip);
}
return weaponsData;
}
// 消耗品
async function rewardItems (roleId: string, roleName: string, dicGood: any, type: number, data: {id:number,cnt:number }) {
let goods = new Array();
let {id, cnt} = data;
let result = await ItemModel.increaseItem(roleId, id, cnt, {roleId, roleName, itemName: dicGood.name, id, type, hid: dicGood.hid||0});
if(result) {
goods.push({
id: id,
name: dicGood.name,
count: cnt,
type: dicGood.goodType,
isCurrency: false
});
}
return goods;
}
// 消耗品
async function rewardCurrency (roleId: string, dicGood: any, data: {id:number,cnt:number }) {
let goods = new Array();
let {id, cnt} = data;
let dicCurrency = CURRENCY.get(id);
if(dicCurrency.type == CURRENCY_TYPE.GOLD) { // 处理元宝
await RoleModel.addGoldFree(roleId, cnt);
} else if(dicCurrency.type == CURRENCY_TYPE.COIN) { // 处理铜币
await RoleModel.addCoin(roleId, cnt);
} else if(dicCurrency.type == CURRENCY_TYPE.ACTION_POINT) { // 处理体力
await setAp(Date.now(), roleId, cnt);
}
goods.push({
id: id,
name: dicGood.name,
count: cnt,
type: dicGood.goodType,
isCurrency: true,
currencyType: dicCurrency.type
});
return goods;
}
interface Item {id: number, count: number, seqId?: number};
interface Equip {id: number, name: string, quality: number, type: number};
interface Bag {id: number, itemName: string, count: number, type: number, hid:number};
export async function handleCost(roleId: string, sid: string, goods: Array<Item>) {
let currencysMap: any = {};
let equips: Array<number> = [];
let bags: Array<Item> = [];
let uids = [{uid: roleId, sid}];
if (!sortConsumes(goods, bags, currencysMap, equips))
return false;
// 检查货币是否充足
if (!!Object.keys(currencysMap).length) {
let role = await RoleModel.findByRoleId(roleId);
for (let key in currencysMap) {
currencysMap[key] = role[key] - currencysMap[key];
if (currencysMap[key] < 0) {
return false;
}
}
}
//检查装备是否存在
if (!!equips.length) {
let resEquips = await EquipModel.getEquips(roleId, equips);
if (resEquips.length < equips.length)
return false;
}
//检查并修改道具
if(bags.length > 0) {
let {hasError, result} = await ItemModel.decreaseItems(roleId, bags);
if(hasError) return false;
pinus.app.get('channelService').pushMessageByUids('onItemUpdate', resResult(STATUS.SUCCESS, {goods: result} ), uids);
}
//删除装备
if (!!equips.length) {
await EquipModel.deleteEquips(roleId, equips);
pinus.app.get('channelService').pushMessageByUids('onEquipDel', resResult(STATUS.SUCCESS, {equips}), uids);
}
//消耗玩家货币
if (!!Object.keys(currencysMap).length) {
await RoleModel.updateRoleInfo(roleId, currencysMap);
pinus.app.get('channelService').pushMessageByUids('onPlayerDataChange', resResult(STATUS.SUCCESS, currencysMap), uids);
}
return true;
}
function sortConsumes(goods: Array<Item>, bags: Array<Item>, currencysMap: any, equips: Array<number>) {
for (let good of goods) {
let goodInfo = getGoodById(good.id);
if (goodInfo.goodType == GOOD_TYPE.EQUIP) { // 装备
if (!!good.seqId) {
equips.push(good.seqId);
} else {
return false;
}
} else {
let {type} = ITID.get(goodInfo.itid);
let curname = getCurNameById(goodInfo.good_id);
if (!!curname) {
if (curname != 'ap') {
currencysMap[curname] = (currencysMap[curname]||0) + good.count;
} else {
return false;
}
} else if (type != CONSUME_TYPE.SKIN){
let index = _.indexOf(bags, {id: good.id});
if (index > 0) {
bags[index].count = bags[index].count + good.count;
} else {
bags.push(good);
}
} else {
return;
}
}
}
return true;
}
export async function addItems(roleId: string, roleName: string, sid: string, goods: Array<Item>) {
let showItems: Array<Item> = [];
let currencysMap: any = {};
let equips: Array<Equip> = [];
let bags: Array<Bag> = [];
let skins: Array<number> = [];
let uids = [{uid: roleId, sid}];
sortItems(goods, bags, skins, currencysMap, equips, showItems);
let equipInfos = [];
for (let equip of equips) {
let equipInfo = await addEquips(roleId, roleName, equip);
showItems.push({id: equip.id, count: 1});
equipInfos.push(equipInfo);
}
//装备推送
if (!!equipInfos.length)
pinus.app.get('channelService').pushMessageByUids('onEquipAdd', resResult(STATUS.SUCCESS, {equipInfos}), uids);
//货币推送
if (!!Object.keys(currencysMap).length) {
let role = await RoleModel.findByRoleId(roleId);
for (let key in currencysMap) {
if (key == 'ap') {
let {ap} = await setAp(Date.now(), roleId, currencysMap[key]);
currencysMap.ap = ap;
} else {
currencysMap[key] += role[key];
}
}
RoleModel.updateRoleInfo(roleId, currencysMap);
pinus.app.get('channelService').pushMessageByUids('onPlayerDataChange', resResult(STATUS.SUCCESS, currencysMap), uids);
}
let bagInfos = [];
for (let item of bags) {
let bagInfo = await addBags(roleId, roleName, item);
showItems.push({id: item.id, count: item.count});
bagInfos.push(bagInfo);
}
//背包除去装备推送
if (!!bagInfos.length)
pinus.app.get('channelService').pushMessageByUids('onItemUpdate', resResult(STATUS.SUCCESS, {goods: bagInfos}), uids);
let skinInfos = [];
for (let skinId of skins) {//皮肤推送
let result = await addSkins(roleId, skinId);
if (!!result) {
showItems.push({id: skinId, count: 1});
skinInfos.push(result);
}
}
if (!!skinInfos.length)
pinus.app.get('channelService').pushMessageByUids('onHeroSkinChange', resResult(STATUS.SUCCESS, {skinInfos}), uids);
return showItems;
}
function sortItems (goods: Array<Item>, bags: Array<Bag>, skins: Array<number>, currencysMap: any, equips: Array<Equip>, showItems: Array<Item>) {
for (let good of goods) {
let goodInfo = getGoodById(good.id);
if (goodInfo.goodType == GOOD_TYPE.EQUIP) { // 装备
for (let i = 0; i < good.count; i++) {
equips.push({id: good.id, name: goodInfo.name, quality: goodInfo.lv, type: goodInfo.goodType});
}
} else {
let {type, isCurrency} = ITID.get(goodInfo.itid);
if (!!isCurrency) {
let curname = getCurNameById(goodInfo.good_id);
if (!!curname) {
let index = _.indexOf(showItems, {id: good.id});
if (index > 0) {
showItems[index].count = showItems[index].count + good.count;
} else {
showItems.push(good);
}
currencysMap[curname] = (currencysMap[curname]||0 )+ good.count;
}
} else if (type == CONSUME_TYPE.SKIN) {
let index = _.indexOf(skins, good.id);
if (index == -1) {
skins.push(good.id);
}
} else {
let index = _.indexOf(bags, {id: good.id});
if (index > 0) {
bags[index].count = bags[index].count + good.count;
} else {
bags.push({id: good.id, count: good.count, itemName: goodInfo.name, hid: goodInfo.hid||0, type});
}
}
}
}
}