113 lines
3.8 KiB
TypeScript
113 lines
3.8 KiB
TypeScript
import { ApiCall } from "tsrpc";
|
|
import { ReqReceive, ResReceive } from '../../../shared/protocols/event/payForDiamond/PtlReceive';
|
|
import { playerCanReceive } from './ApiCanReceive';
|
|
import { PublicShared } from "../../../shared/public/public";
|
|
import { ChatFun } from "../../../public/chat";
|
|
|
|
type diamondWeightGroup = {
|
|
weight: number;
|
|
numrange: [ min: number, max: number];
|
|
};
|
|
|
|
/**
|
|
* @param groups 各分组及其权重
|
|
*/
|
|
function randomWithWeight(groups: diamondWeightGroup[]) {
|
|
let maxAmount: number;
|
|
let totalWeights = 0;
|
|
for (const group of groups) {
|
|
totalWeights += group.weight;
|
|
if (!maxAmount) {
|
|
maxAmount = group.numrange[1];
|
|
} else {
|
|
maxAmount = Math.min(maxAmount, group.numrange[1]);
|
|
}
|
|
}
|
|
const randomValue = Math.random() * totalWeights; // 随机值落在[0, totalWeights) 之间
|
|
let currSum = 0;
|
|
for (const group of groups) {
|
|
if (currSum <= randomValue && randomValue < currSum + group.weight) {
|
|
return { group, maxAmount };
|
|
} else {
|
|
currSum += group.weight;
|
|
}
|
|
}
|
|
const length = groups.length;
|
|
return { group: groups[length - 1], maxAmount };
|
|
}
|
|
|
|
/**
|
|
* 计算玩家分得的钻石数量
|
|
* @param remaining
|
|
* @param group
|
|
* @param maxAmount
|
|
*/
|
|
function calcDiamondGot(remaining: number, group: diamondWeightGroup, maxAmount: number) {
|
|
const [min, max] = group.numrange;
|
|
const randomAmount = Math.floor(Math.random() * (max - min)) + min + 1; // max 值应能够取到, 故 +1
|
|
// 剩余数额小于组内随机得到的值, 全给吧
|
|
if (randomAmount > remaining) {
|
|
return remaining;
|
|
}
|
|
// 随机值大于最大值, 取最大值
|
|
if (randomAmount > maxAmount) {
|
|
return maxAmount;
|
|
}
|
|
return randomAmount;
|
|
}
|
|
|
|
export default async function (call: ApiCall<ReqReceive, ResReceive>) {
|
|
const canReceiveResult = await playerCanReceive(call);
|
|
if (canReceiveResult) {
|
|
if (!canReceiveResult.result) {
|
|
return call.succ({
|
|
amount: 0,
|
|
timesRemaining: 0
|
|
});
|
|
}
|
|
const activityData = canReceiveResult.activityInfo.data;
|
|
const remaining = activityData['remaining']? activityData['remaining'] : activityData['totalmoney'];
|
|
const { group, maxAmount } = randomWithWeight(activityData['groupConf']['arr']);
|
|
const gotAmount = calcDiamondGot(remaining, group, maxAmount);
|
|
// 减去余额
|
|
const filter = {
|
|
hdid: call.req.activityId,
|
|
$or: [
|
|
{'data.remaining': { $exists: false }},
|
|
{$expr: {$gte: [ `$data.remaining - ${gotAmount}`, 0 ]}},
|
|
],
|
|
};
|
|
const updateDoc = {
|
|
$set: { 'data.remaining': `$data.remaining - ${gotAmount}` }
|
|
}
|
|
const updateResult = await G.mongodb.collection('hdinfo').updateOne(filter, updateDoc);
|
|
// 更新成功
|
|
if (updateResult.modifiedCount) {
|
|
// 请求返回
|
|
call.succ({
|
|
amount: gotAmount,
|
|
timesRemaining: 0
|
|
});
|
|
// 添加玩家领取记录
|
|
const zeroTime = PublicShared.getToDayZeroTime();
|
|
const setObj = {};
|
|
setObj[zeroTime] = gotAmount;
|
|
G.mongodb.cEvent('payForDiamond').updateOne({ uid: call.uid }, {
|
|
$set: setObj
|
|
});
|
|
}
|
|
// 发送炫耀
|
|
if (gotAmount >= activityData['groupConf']['base']['loglimit']) {
|
|
ChatFun.newMsg({
|
|
type: 'local',
|
|
msg: G.gc.pmd.get_hero_star5_pmd,
|
|
time: G.time,
|
|
sender: 'system',
|
|
otherData: {
|
|
pmd: true,
|
|
args: [gotAmount]
|
|
}
|
|
});
|
|
}
|
|
}
|
|
} |