fix: Ref 게임 로직과 시나리오 풀 호환을 보정
월 경계, 전투 기술 상한, 연감과 베팅·설문·경매 정산 순서를 Ref 계약에 맞춘다.\n\n시나리오 일반 풀을 ENGINE mutation과 logical tick 기반으로 직렬화하고 914·915 catalog 및 조건부 100기 pool 실행 경계를 추가한다.\n\n경매 worker는 세대별 durable event만 만들고 ENGINE이 row lock 후 상태 전이와 정산을 단일 transaction으로 소유한다.
This commit is contained in:
@@ -565,6 +565,7 @@ export const settleTournamentOutcome = async (options: {
|
||||
type: 'tournamentBettingPayout',
|
||||
requestId: `tournament:${settledState.bettingId}:betting-payout`,
|
||||
bettingId: settledState.bettingId,
|
||||
tournamentType: settledState.type,
|
||||
payouts: payoutInfo.payouts,
|
||||
reason: 'winner_payout',
|
||||
});
|
||||
|
||||
@@ -617,11 +617,22 @@ export const buildBettingPayouts = (
|
||||
winnerId: number,
|
||||
entries: TournamentBetEntry[]
|
||||
): { payouts: Array<{ generalId: number; amount: number }>; total: number; refundAll: boolean } => {
|
||||
const total = entries.reduce((sum, entry) => sum + entry.amount, 0);
|
||||
const aggregated = new Map<string, TournamentBetEntry>();
|
||||
for (const entry of entries) {
|
||||
const key = `${entry.generalId}:${entry.targetId}`;
|
||||
const previous = aggregated.get(key);
|
||||
if (previous) {
|
||||
previous.amount += entry.amount;
|
||||
} else {
|
||||
aggregated.set(key, { ...entry });
|
||||
}
|
||||
}
|
||||
const normalizedEntries = [...aggregated.values()];
|
||||
const total = normalizedEntries.reduce((sum, entry) => sum + entry.amount, 0);
|
||||
if (total <= 0) {
|
||||
return { payouts: [], total: 0, refundAll: false };
|
||||
}
|
||||
const winners = entries.filter((entry) => entry.targetId === winnerId);
|
||||
const winners = normalizedEntries.filter((entry) => entry.targetId === winnerId);
|
||||
const winnersTotal = winners.reduce((sum, entry) => sum + entry.amount, 0);
|
||||
if (winnersTotal <= 0) {
|
||||
// Legacy Betting::_calcRewardExclusive() builds a refund candidate list
|
||||
|
||||
Reference in New Issue
Block a user