186 lines
7.5 KiB
TypeScript
186 lines
7.5 KiB
TypeScript
import {ObjectId} from 'mongodb';
|
||
import {ApiCall} from 'tsrpc';
|
||
import {CollectionShiwu} from '../module/collection_shiwu';
|
||
import {PublicShared} from '../shared/public/public';
|
||
import {HeroFun} from './hero';
|
||
import {call} from './player';
|
||
|
||
type shiwuType = CollectionShiwu;
|
||
type shiwuChange = Partial<Omit<{
|
||
[k in keyof CollectionShiwu]: CollectionShiwu[k]
|
||
}, '_id'>>;
|
||
|
||
export class ShiwuFun {
|
||
static get _conf() {
|
||
return G.gc.shiwucom.base;
|
||
}
|
||
|
||
/**获取饰物 */
|
||
static async getShiwu(call: ApiCall, oid: string): Promise<CollectionShiwu>;
|
||
static async getShiwu(call: ApiCall, oid: string[]): Promise<CollectionShiwu[]>;
|
||
static async getShiwu(call: ApiCall, oid: string | string[]) {
|
||
if (typeof oid == 'string') {
|
||
let {_id, ...data} = await G.mongodb.collection('shiwu').findOne(
|
||
{_id: G.mongodb.conversionId(oid)}
|
||
)
|
||
data['_id'] = oid;
|
||
return data
|
||
} else {
|
||
let oids = [].concat(oid).map(v => G.mongodb.conversionId(v))
|
||
let ss = await G.mongodb.collection('shiwu').find({uid: call.uid, _id: {$in: oids}}).toArray();
|
||
return ss.map(v => G.mongodb.conversionIdObj(v));
|
||
}
|
||
|
||
}
|
||
|
||
/**修改饰物属性 */
|
||
static async changeShiwuAttr(call: call, shiwu: Pick<shiwuType, '_id'> & Partial<Omit<shiwuType, '_id'>>, change: shiwuChange, changeHero = true) {
|
||
|
||
//穿戴饰物时该装备穿戴在另一个英雄身上
|
||
if (change.wearId != undefined && shiwu.wearId && shiwu.wearId != change.wearId && changeHero) {
|
||
let takeHero = await HeroFun.getHero(call, shiwu.wearId);
|
||
if (takeHero) {
|
||
let _shiwu = Object.assign({}, takeHero.shiwu);
|
||
let _pos = Object.keys(_shiwu).filter(pos => _shiwu[pos]._id == shiwu._id)[0];
|
||
|
||
if (_pos) {
|
||
_shiwu[_pos] = null;
|
||
delete _shiwu[_pos];
|
||
await HeroFun.changeHeroAttr(call, takeHero, {shiwu: _shiwu});
|
||
}
|
||
}
|
||
}
|
||
|
||
Object.assign(shiwu, change);
|
||
|
||
//属性发生变化并且穿戴在英雄身上时
|
||
if (change.wearId == undefined && shiwu.wearId) {
|
||
let takeHero = await HeroFun.getHero(call, shiwu.wearId);
|
||
if (takeHero) {
|
||
let _shiwu = Object.assign({}, takeHero.shiwu);
|
||
let _pos = Object.keys(_shiwu).filter(pos => _shiwu[pos]._id == shiwu._id)[0];
|
||
|
||
if (_pos) {
|
||
_shiwu[_pos] = this.fmtHeroShiwu(shiwu as shiwuType);
|
||
await HeroFun.changeHeroAttr(call, takeHero, {shiwu: _shiwu});
|
||
}
|
||
}
|
||
}
|
||
|
||
// for (let k in change) {
|
||
// G.redis.set('shiwu', call.uid, shiwu._id, k as keyof shiwuType, change[k]);
|
||
// }
|
||
G.mongodb.collection('shiwu').updateOne(
|
||
{uid: call.uid, _id: new ObjectId(shiwu._id)}, {$set: {...change}}
|
||
);
|
||
call.addEventMsg('msg_s2c/ShiwuChange', shiwu._id, change);
|
||
}
|
||
|
||
/**随机饰物基础属性 */
|
||
static randomJichu(shiwu: Pick<shiwuType, 'shiwuId' | 'colour'>): shiwuType['jichu'] {
|
||
let conf = G.gc.shiwu[shiwu.shiwuId];
|
||
let jichu: shiwuType['jichu'] = [];
|
||
let buffKeys = Object.keys(conf.buff);
|
||
|
||
for (let key of buffKeys) {
|
||
jichu.push(key);
|
||
jichu.push(Math.floor(PublicShared.randomNum(conf.buff[key][0], conf.buff[key][1]) * this._conf.jichu_colour[shiwu.colour]));
|
||
}
|
||
|
||
return jichu;
|
||
}
|
||
|
||
/**随机饰物附加属性 */
|
||
static randomFujiaAll(shiwu: Pick<shiwuType, 'colour' | 'fujia'> & { shiwuId?: string; }, lockArr: number[] = []) {
|
||
let lv = G.gc.shiwu[shiwu?.shiwuId].lv || 1;
|
||
let index = G.gc.shiwucom.base.fujia_colour.buffRandom.findIndex(v => lv >= v.range[0] && lv <= v.range[1]);
|
||
// 附加属性颜色超过 5 大于等 饰物颜色减1 (随机最大属性池,取其最大buff)
|
||
// let allOrange = shiwu.fujia.filter(f => f?.colour >= 5).length >= shiwu.colour - 1;
|
||
let allOrange = shiwu.fujia.filter(f => f?.colour >= 5).length >= shiwu.fujia.length;
|
||
|
||
for (let num = 0; num < shiwu.colour - 1; num++) {
|
||
let fjsx = shiwu.fujia[num];
|
||
|
||
// if (!fjsx) {
|
||
// // 按等级筛选 随机属性池
|
||
// shiwu.fujia[num] = {
|
||
// ...this.randomFujia(index)
|
||
// };
|
||
// } else {
|
||
// // 无特殊条件 附加颜色超过或等于5 || 有特殊条件 但被锁定 // 此两种情况不随机
|
||
// if (!allOrange && fjsx.colour >= 5) continue;
|
||
// if (allOrange && lockArr.includes(num)) continue;
|
||
|
||
// shiwu.fujia[num] = {
|
||
// ...this.randomFujia(allOrange ? G.gc.shiwucom.base.fujia_colour.buffRandom.length - 1 : index, allOrange)
|
||
// };
|
||
// }
|
||
|
||
// 普通洗练
|
||
if (!allOrange || !fjsx) {
|
||
if (fjsx && fjsx.colour >= 5) continue
|
||
// 按等级筛选 随机属性池
|
||
shiwu.fujia[num] = {
|
||
...this.randomFujia(index)
|
||
};
|
||
} else {
|
||
// 无特殊条件 附加颜色超过或等于5 || 有特殊条件 但被锁定 // 此两种情况不随机
|
||
if (!allOrange && fjsx.colour >= 5) continue;
|
||
if (allOrange && lockArr.includes(num)) continue;
|
||
|
||
shiwu.fujia[num] = {
|
||
...this.randomFujia(index, allOrange)
|
||
};
|
||
}
|
||
}
|
||
}
|
||
|
||
/**随机饰物专属属性 */
|
||
static randomZhuanshu(shiwu: Pick<shiwuType, 'shiwuId' | 'colour' | 'zhuanshu'>) {
|
||
if (shiwu.colour < 5) return;
|
||
if (!shiwu.zhuanshu && (PublicShared.randomNum(1, 1000) < G.gc.shiwu[shiwu.shiwuId].zhuanshu)) return;
|
||
|
||
let isSkill = PublicShared.randomNum(1, 10) <= this._conf.chongzhurate.skill_zhuanshu;
|
||
if (!isSkill) {
|
||
var {p, ...buff} = this._conf.buff_zhuanshu.random();
|
||
var buffKey = Object.keys(buff)[0];
|
||
var buffVal = buff[buffKey];
|
||
}
|
||
|
||
shiwu.zhuanshu = {
|
||
hero: this._conf.hero_zhuanshu.random().toString(),
|
||
buff: isSkill ? null : [buffKey, buffVal],
|
||
skill: isSkill ? this._conf.skill_zhuanshu.random().id : '',
|
||
};
|
||
}
|
||
|
||
/**格式化为英雄穿戴的饰物数据 */
|
||
static fmtHeroShiwu(shiwu: shiwuType) {
|
||
let {uid, wearId, ...ops} = shiwu;
|
||
return ops;
|
||
}
|
||
|
||
static randomFujia(index: number, max = false) {
|
||
let buff = (this._conf.fujia_colour.buffRandom[index].buff as k_v<[number, number]>[]).random();
|
||
let buffKey = Object.keys(buff)[0];
|
||
let buffVal = buff[buffKey];
|
||
let multiplyNum = buffVal[0].toString().split('.').length > 1 ? 10000 : 1;
|
||
// 是否取随机buff最大值
|
||
let val = max ? buffVal[1] : PublicShared.randomNum(buffVal[0] * multiplyNum, buffVal[1] * multiplyNum) / multiplyNum;
|
||
val = val > buffVal[1] ? buffVal[1] : val
|
||
let colour: number;
|
||
let mul = (val - buffVal[0]) / (buffVal[1] - buffVal[0]);
|
||
|
||
for (let c of this._conf.fujia_colour.color) {
|
||
if (mul < c.range[0]) break;
|
||
colour = c.color;
|
||
if (mul < c.range[1]) break;
|
||
}
|
||
|
||
return {
|
||
colour: colour || this._conf.fujia_colour.color[0].color,
|
||
buffKey: buffKey,
|
||
buffVal: val
|
||
};
|
||
}
|
||
} |