koishipro-core.js 1.2.4 → 1.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +201 -0
- package/dist/index.cjs.map +4 -4
- package/dist/index.mjs +206 -0
- package/dist/index.mjs.map +3 -3
- package/dist/src/advancors/index.d.ts +1 -0
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1410,6 +1410,211 @@ var SummonPlaceAdvancor = (placeAndPosition = {}) => MapAdvancor(
|
|
|
1410
1410
|
})
|
|
1411
1411
|
);
|
|
1412
1412
|
|
|
1413
|
+
// src/advancors/select-card-advancor.ts
|
|
1414
|
+
import {
|
|
1415
|
+
IndexResponse,
|
|
1416
|
+
YGOProMsgSelectCard,
|
|
1417
|
+
YGOProMsgSelectSum,
|
|
1418
|
+
YGOProMsgSelectTribute,
|
|
1419
|
+
YGOProMsgSelectUnselectCard
|
|
1420
|
+
} from "ygopro-msg-encode";
|
|
1421
|
+
var SelectCardAdvancor = (...cards) => {
|
|
1422
|
+
const remainingCards = cards.slice();
|
|
1423
|
+
const applyFilter = (items, filter) => {
|
|
1424
|
+
return items.filter(
|
|
1425
|
+
(item) => Object.entries(filter).every(
|
|
1426
|
+
([key, value]) => value == null || item[key] === value
|
|
1427
|
+
)
|
|
1428
|
+
);
|
|
1429
|
+
};
|
|
1430
|
+
const pickCard = (items, min, max) => {
|
|
1431
|
+
const picked = [];
|
|
1432
|
+
const usedIndices = /* @__PURE__ */ new Set();
|
|
1433
|
+
const usedFilters = /* @__PURE__ */ new Set();
|
|
1434
|
+
for (const filter of remainingCards) {
|
|
1435
|
+
if (picked.length >= max) break;
|
|
1436
|
+
let matchIndex = -1;
|
|
1437
|
+
for (let i = 0; i < items.length; i++) {
|
|
1438
|
+
if (usedIndices.has(i)) continue;
|
|
1439
|
+
if (applyFilter([items[i]], filter).length === 1) {
|
|
1440
|
+
matchIndex = i;
|
|
1441
|
+
break;
|
|
1442
|
+
}
|
|
1443
|
+
}
|
|
1444
|
+
if (matchIndex < 0) continue;
|
|
1445
|
+
picked.push(IndexResponse(matchIndex));
|
|
1446
|
+
usedIndices.add(matchIndex);
|
|
1447
|
+
usedFilters.add(filter);
|
|
1448
|
+
}
|
|
1449
|
+
if (picked.length < min) {
|
|
1450
|
+
return void 0;
|
|
1451
|
+
}
|
|
1452
|
+
for (let i = remainingCards.length - 1; i >= 0; i--) {
|
|
1453
|
+
if (usedFilters.has(remainingCards[i])) {
|
|
1454
|
+
remainingCards.splice(i, 1);
|
|
1455
|
+
}
|
|
1456
|
+
}
|
|
1457
|
+
return picked;
|
|
1458
|
+
};
|
|
1459
|
+
return MapAdvancor(
|
|
1460
|
+
MapAdvancorHandler(YGOProMsgSelectCard, (msg) => {
|
|
1461
|
+
const picked = pickCard(msg.cards, msg.min, msg.max);
|
|
1462
|
+
if (picked) {
|
|
1463
|
+
return msg.prepareResponse(picked);
|
|
1464
|
+
}
|
|
1465
|
+
}),
|
|
1466
|
+
MapAdvancorHandler(YGOProMsgSelectUnselectCard, (msg) => {
|
|
1467
|
+
const picked = pickCard(msg.selectableCards, 1, 1);
|
|
1468
|
+
if (picked) {
|
|
1469
|
+
return msg.prepareResponse(picked[0]);
|
|
1470
|
+
}
|
|
1471
|
+
}),
|
|
1472
|
+
MapAdvancorHandler(YGOProMsgSelectSum, (msg) => {
|
|
1473
|
+
const decodeOpParam = (opParam) => {
|
|
1474
|
+
const u = opParam >>> 0;
|
|
1475
|
+
if ((u & 2147483648) !== 0) {
|
|
1476
|
+
return { amount: u & 2147483647, extra: 0 };
|
|
1477
|
+
}
|
|
1478
|
+
return { amount: u & 65535, extra: u >>> 16 & 65535 };
|
|
1479
|
+
};
|
|
1480
|
+
const amountOf = (c) => decodeOpParam(c.opParam).amount;
|
|
1481
|
+
const mustSum = (msg.mustSelectCards ?? []).reduce(
|
|
1482
|
+
(acc, c) => acc + amountOf(c),
|
|
1483
|
+
0
|
|
1484
|
+
);
|
|
1485
|
+
const mustCount = (msg.mustSelectCards ?? []).length;
|
|
1486
|
+
const pickedIdx = [];
|
|
1487
|
+
const pickedIdxSet = /* @__PURE__ */ new Set();
|
|
1488
|
+
const totalSum = () => mustSum + pickedIdx.reduce((acc, i) => acc + amountOf(msg.cards[i]), 0);
|
|
1489
|
+
const totalCount = () => mustCount + pickedIdx.length;
|
|
1490
|
+
const filterMatch = /* @__PURE__ */ new Map();
|
|
1491
|
+
for (let fi = 0; fi < remainingCards.length; fi++) {
|
|
1492
|
+
const f = remainingCards[fi];
|
|
1493
|
+
const idx = msg.cards.findIndex(
|
|
1494
|
+
(c, i) => !pickedIdxSet.has(i) && applyFilter([c], f).length === 1
|
|
1495
|
+
);
|
|
1496
|
+
if (idx < 0) continue;
|
|
1497
|
+
pickedIdx.push(idx);
|
|
1498
|
+
pickedIdxSet.add(idx);
|
|
1499
|
+
filterMatch.set(fi, idx);
|
|
1500
|
+
}
|
|
1501
|
+
const consumeRemainingByFinalPick = () => {
|
|
1502
|
+
const usedFilterIdx = /* @__PURE__ */ new Set();
|
|
1503
|
+
for (const [fi, idx] of filterMatch.entries()) {
|
|
1504
|
+
if (pickedIdxSet.has(idx)) usedFilterIdx.add(fi);
|
|
1505
|
+
}
|
|
1506
|
+
for (let i = remainingCards.length - 1; i >= 0; i--) {
|
|
1507
|
+
if (usedFilterIdx.has(i)) remainingCards.splice(i, 1);
|
|
1508
|
+
}
|
|
1509
|
+
};
|
|
1510
|
+
const target = msg.sumVal;
|
|
1511
|
+
if (msg.mode === 1) {
|
|
1512
|
+
let s = totalSum();
|
|
1513
|
+
if (s < target) {
|
|
1514
|
+
for (let i = 0; i < msg.cards.length; i++) {
|
|
1515
|
+
if (s >= target) break;
|
|
1516
|
+
if (pickedIdxSet.has(i)) continue;
|
|
1517
|
+
pickedIdx.push(i);
|
|
1518
|
+
pickedIdxSet.add(i);
|
|
1519
|
+
s += amountOf(msg.cards[i]);
|
|
1520
|
+
}
|
|
1521
|
+
}
|
|
1522
|
+
if (s < target) return;
|
|
1523
|
+
const removable = (pos) => {
|
|
1524
|
+
const idx = pickedIdx[pos];
|
|
1525
|
+
const v = amountOf(msg.cards[idx]);
|
|
1526
|
+
return s - v >= target;
|
|
1527
|
+
};
|
|
1528
|
+
for (let pos = pickedIdx.length - 1; pos >= 0; pos--) {
|
|
1529
|
+
if (!removable(pos)) continue;
|
|
1530
|
+
const idx = pickedIdx[pos];
|
|
1531
|
+
const v = amountOf(msg.cards[idx]);
|
|
1532
|
+
pickedIdx.splice(pos, 1);
|
|
1533
|
+
pickedIdxSet.delete(idx);
|
|
1534
|
+
s -= v;
|
|
1535
|
+
}
|
|
1536
|
+
for (const idx of pickedIdx) {
|
|
1537
|
+
if (s - amountOf(msg.cards[idx]) >= target) return;
|
|
1538
|
+
}
|
|
1539
|
+
consumeRemainingByFinalPick();
|
|
1540
|
+
return msg.prepareResponse(pickedIdx.map((i) => IndexResponse(i)));
|
|
1541
|
+
}
|
|
1542
|
+
const baseSum = mustSum;
|
|
1543
|
+
const baseCount = mustCount;
|
|
1544
|
+
const sumLeft = target - baseSum;
|
|
1545
|
+
const minLeft = Math.max(0, msg.min - baseCount);
|
|
1546
|
+
const maxLeft = Math.max(0, msg.max - baseCount);
|
|
1547
|
+
if (sumLeft < 0) return;
|
|
1548
|
+
if (maxLeft < 0) return;
|
|
1549
|
+
const preSum = pickedIdx.reduce(
|
|
1550
|
+
(acc, i) => acc + amountOf(msg.cards[i]),
|
|
1551
|
+
0
|
|
1552
|
+
);
|
|
1553
|
+
const preCount = pickedIdx.length;
|
|
1554
|
+
const sumNeed = sumLeft - preSum;
|
|
1555
|
+
const minNeed = Math.max(0, minLeft - preCount);
|
|
1556
|
+
const maxNeed = Math.max(0, maxLeft - preCount);
|
|
1557
|
+
if (sumNeed < 0) return;
|
|
1558
|
+
if (maxNeed < 0) return;
|
|
1559
|
+
const candidates = [];
|
|
1560
|
+
for (let i = 0; i < msg.cards.length; i++) {
|
|
1561
|
+
if (pickedIdxSet.has(i)) continue;
|
|
1562
|
+
const v = amountOf(msg.cards[i]);
|
|
1563
|
+
if (v <= sumNeed) candidates.push({ idx: i, v });
|
|
1564
|
+
}
|
|
1565
|
+
const keyOf = (sum, cnt) => `${sum}|${cnt}`;
|
|
1566
|
+
const dp = /* @__PURE__ */ new Map();
|
|
1567
|
+
dp.set(keyOf(0, 0), {});
|
|
1568
|
+
for (const c of candidates) {
|
|
1569
|
+
const snapshot = Array.from(dp.keys());
|
|
1570
|
+
for (const k of snapshot) {
|
|
1571
|
+
const [sStr, cStr] = k.split("|");
|
|
1572
|
+
const s = Number(sStr);
|
|
1573
|
+
const cnt = Number(cStr);
|
|
1574
|
+
const ns = s + c.v;
|
|
1575
|
+
const ncnt = cnt + 1;
|
|
1576
|
+
if (ns > sumNeed) continue;
|
|
1577
|
+
if (ncnt > maxNeed) continue;
|
|
1578
|
+
const nk = keyOf(ns, ncnt);
|
|
1579
|
+
if (dp.has(nk)) continue;
|
|
1580
|
+
dp.set(nk, { prevKey: k, takeIdx: c.idx });
|
|
1581
|
+
}
|
|
1582
|
+
}
|
|
1583
|
+
let bestKey;
|
|
1584
|
+
for (let cnt = minNeed; cnt <= maxNeed; cnt++) {
|
|
1585
|
+
const k = keyOf(sumNeed, cnt);
|
|
1586
|
+
if (dp.has(k)) {
|
|
1587
|
+
bestKey = k;
|
|
1588
|
+
break;
|
|
1589
|
+
}
|
|
1590
|
+
}
|
|
1591
|
+
if (!bestKey) return;
|
|
1592
|
+
const extraIdx = [];
|
|
1593
|
+
let curKey = bestKey;
|
|
1594
|
+
while (curKey !== keyOf(0, 0)) {
|
|
1595
|
+
const node = dp.get(curKey);
|
|
1596
|
+
if (typeof node.takeIdx === "number") extraIdx.push(node.takeIdx);
|
|
1597
|
+
curKey = node.prevKey;
|
|
1598
|
+
}
|
|
1599
|
+
extraIdx.reverse();
|
|
1600
|
+
for (const i of extraIdx) {
|
|
1601
|
+
pickedIdx.push(i);
|
|
1602
|
+
pickedIdxSet.add(i);
|
|
1603
|
+
}
|
|
1604
|
+
if (totalCount() < msg.min || totalCount() > msg.max) return;
|
|
1605
|
+
if (totalSum() !== target) return;
|
|
1606
|
+
consumeRemainingByFinalPick();
|
|
1607
|
+
return msg.prepareResponse(pickedIdx.map((i) => IndexResponse(i)));
|
|
1608
|
+
}),
|
|
1609
|
+
MapAdvancorHandler(YGOProMsgSelectTribute, (msg) => {
|
|
1610
|
+
const picked = pickCard(msg.cards, msg.min, msg.max);
|
|
1611
|
+
if (picked) {
|
|
1612
|
+
return msg.prepareResponse(picked);
|
|
1613
|
+
}
|
|
1614
|
+
})
|
|
1615
|
+
);
|
|
1616
|
+
};
|
|
1617
|
+
|
|
1413
1618
|
// index.ts
|
|
1414
1619
|
if (typeof globalThis !== "undefined" && !globalThis.Buffer) {
|
|
1415
1620
|
globalThis.Buffer = Buffer2;
|
|
@@ -1439,6 +1644,7 @@ export {
|
|
|
1439
1644
|
PlayerViewAdvancor,
|
|
1440
1645
|
QUERY_BUFFER_SIZE,
|
|
1441
1646
|
REGISTRY_BUFFER_SIZE,
|
|
1647
|
+
SelectCardAdvancor,
|
|
1442
1648
|
SlientAdvancor,
|
|
1443
1649
|
SqljsCardReader,
|
|
1444
1650
|
StaticAdvancor,
|