@bct-app/game-engine 0.1.19 → 0.1.21
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.d.mts +1 -3
- package/dist/index.d.ts +1 -3
- package/dist/index.js +17 -16
- package/dist/index.mjs +17 -16
- package/package.json +2 -2
package/dist/index.d.mts
CHANGED
|
@@ -133,9 +133,6 @@ type TDslPlayer = TPlayer & {
|
|
|
133
133
|
characterKind: string | undefined;
|
|
134
134
|
reminderMarks: string[];
|
|
135
135
|
effectiveAlive: boolean;
|
|
136
|
-
diedThisTurn: boolean;
|
|
137
|
-
wasExecuted: boolean;
|
|
138
|
-
wasExecutedToday: boolean;
|
|
139
136
|
};
|
|
140
137
|
type TDslNomination = {
|
|
141
138
|
nominator: number;
|
|
@@ -161,6 +158,7 @@ type TDslContext = {
|
|
|
161
158
|
};
|
|
162
159
|
currentTimeline: {
|
|
163
160
|
turn: number;
|
|
161
|
+
previousTurn: number;
|
|
164
162
|
phase: string;
|
|
165
163
|
time: TTimeline['time'] | undefined;
|
|
166
164
|
isFirstOfPhase: boolean;
|
package/dist/index.d.ts
CHANGED
|
@@ -133,9 +133,6 @@ type TDslPlayer = TPlayer & {
|
|
|
133
133
|
characterKind: string | undefined;
|
|
134
134
|
reminderMarks: string[];
|
|
135
135
|
effectiveAlive: boolean;
|
|
136
|
-
diedThisTurn: boolean;
|
|
137
|
-
wasExecuted: boolean;
|
|
138
|
-
wasExecutedToday: boolean;
|
|
139
136
|
};
|
|
140
137
|
type TDslNomination = {
|
|
141
138
|
nominator: number;
|
|
@@ -161,6 +158,7 @@ type TDslContext = {
|
|
|
161
158
|
};
|
|
162
159
|
currentTimeline: {
|
|
163
160
|
turn: number;
|
|
161
|
+
previousTurn: number;
|
|
164
162
|
phase: string;
|
|
165
163
|
time: TTimeline['time'] | undefined;
|
|
166
164
|
isFirstOfPhase: boolean;
|
package/dist/index.js
CHANGED
|
@@ -519,19 +519,20 @@ var applyStatusChange = createEffectHandler("STATUS_CHANGE", ({
|
|
|
519
519
|
effect,
|
|
520
520
|
payloads,
|
|
521
521
|
makePlayersEffect,
|
|
522
|
-
|
|
522
|
+
operationTurn,
|
|
523
523
|
abilityMap,
|
|
524
|
-
operation
|
|
524
|
+
operation,
|
|
525
|
+
operationTime
|
|
525
526
|
}) => {
|
|
526
527
|
const maybeStatus = getSourceValue(effect.source, payloads);
|
|
527
528
|
if (maybeStatus === "DEAD") {
|
|
528
529
|
const ability = abilityMap.get(operation.abilityId);
|
|
529
|
-
const turn = operationInTimelineIdx >= 0 ? operationInTimelineIdx : 0;
|
|
530
530
|
const cause = effect.deathCause ?? (ability?.category === "STORYTELLER" ? "STORYTELLER" : "ABILITY");
|
|
531
531
|
makePlayersEffect.forEach((player) => {
|
|
532
532
|
player.isDead = true;
|
|
533
533
|
player.deathCause = cause;
|
|
534
|
-
player.deathTurn =
|
|
534
|
+
player.deathTurn = operationTurn;
|
|
535
|
+
player.deathTime = operationTime;
|
|
535
536
|
});
|
|
536
537
|
return;
|
|
537
538
|
}
|
|
@@ -540,6 +541,7 @@ var applyStatusChange = createEffectHandler("STATUS_CHANGE", ({
|
|
|
540
541
|
player.isDead = false;
|
|
541
542
|
delete player.deathCause;
|
|
542
543
|
delete player.deathTurn;
|
|
544
|
+
delete player.deathTime;
|
|
543
545
|
});
|
|
544
546
|
return;
|
|
545
547
|
}
|
|
@@ -562,18 +564,14 @@ var effectHandlers = {
|
|
|
562
564
|
};
|
|
563
565
|
|
|
564
566
|
// src/dsl/context.ts
|
|
565
|
-
var decoratePlayer = (player, characterMap
|
|
567
|
+
var decoratePlayer = (player, characterMap) => {
|
|
566
568
|
const isDead = Boolean(player.isDead);
|
|
567
569
|
const retainsBypass = isDead && (player.retainsAbility === "ALIVENESS" || player.retainsAbility === "ALL");
|
|
568
|
-
const wasExecuted = isDead && player.deathCause === "EXECUTION";
|
|
569
570
|
return {
|
|
570
571
|
...player,
|
|
571
572
|
characterKind: characterMap.get(player.characterId)?.kind,
|
|
572
573
|
reminderMarks: (player.reminders ?? []).map((r) => r.mark),
|
|
573
|
-
effectiveAlive: !isDead || retainsBypass
|
|
574
|
-
diedThisTurn: isDead && typeof player.deathTurn === "number" && player.deathTurn === currentTurn,
|
|
575
|
-
wasExecuted,
|
|
576
|
-
wasExecutedToday: wasExecuted && player.deathTurn === currentTurn
|
|
574
|
+
effectiveAlive: !isDead || retainsBypass
|
|
577
575
|
};
|
|
578
576
|
};
|
|
579
577
|
var isExecutionTimeline = (tl) => {
|
|
@@ -581,7 +579,7 @@ var isExecutionTimeline = (tl) => {
|
|
|
581
579
|
return (tl.operations ?? []).some((op) => op.kind === "execution");
|
|
582
580
|
};
|
|
583
581
|
var buildDslContextFromDerived = (derived, payload = []) => {
|
|
584
|
-
const players = derived.players.map((p) => decoratePlayer(p, derived.characterMap
|
|
582
|
+
const players = derived.players.map((p) => decoratePlayer(p, derived.characterMap));
|
|
585
583
|
const effector = players.find((p) => p.seat === derived.effectorSeat);
|
|
586
584
|
const aliveCount = players.filter((p) => !p.isDead).length;
|
|
587
585
|
const deadCount = players.length - aliveCount;
|
|
@@ -609,6 +607,7 @@ var buildDslContextFromDerived = (derived, payload = []) => {
|
|
|
609
607
|
},
|
|
610
608
|
currentTimeline: {
|
|
611
609
|
turn: derived.currentTurn,
|
|
610
|
+
previousTurn: derived.currentTurn - 1,
|
|
612
611
|
phase: derived.currentPhase,
|
|
613
612
|
time: derived.currentPhase === "NIGHT" ? "night" : derived.currentPhase === "DAY" ? "day" : void 0,
|
|
614
613
|
isFirstOfPhase: derived.isFirstOfPhase,
|
|
@@ -638,8 +637,8 @@ var buildDslContextFromLifetime = ({
|
|
|
638
637
|
const currentTime = nowTl?.time;
|
|
639
638
|
const currentPhase = currentTime === "night" ? "NIGHT" : currentTime === "day" ? "DAY" : "NIGHT";
|
|
640
639
|
const playersRaw = snapshotSeatMap ? [...snapshotSeatMap.values()] : [];
|
|
641
|
-
const players = playersRaw.map((p) => decoratePlayer(p, characterMap
|
|
642
|
-
const effectorDecorated = effector ? players.find((p) => p.seat === effector.seat) ?? decoratePlayer(effector, characterMap
|
|
640
|
+
const players = playersRaw.map((p) => decoratePlayer(p, characterMap));
|
|
641
|
+
const effectorDecorated = effector ? players.find((p) => p.seat === effector.seat) ?? decoratePlayer(effector, characterMap) : void 0;
|
|
643
642
|
const todayOps = timelines.filter((tl) => tl.turn === currentTurn && tl.time === "day").flatMap((tl) => tl.operations ?? []);
|
|
644
643
|
const tonightOps = timelines.filter((tl) => tl.turn === currentTurn && tl.time === "night").flatMap((tl) => tl.operations ?? []);
|
|
645
644
|
const yesterdayDayOps = timelines.filter((tl) => tl.turn === currentTurn - 1 && tl.time === "day").flatMap((tl) => tl.operations ?? []);
|
|
@@ -681,6 +680,7 @@ var buildDslContextFromLifetime = ({
|
|
|
681
680
|
},
|
|
682
681
|
currentTimeline: {
|
|
683
682
|
turn: currentTurn,
|
|
683
|
+
previousTurn: currentTurn - 1,
|
|
684
684
|
phase: currentPhase,
|
|
685
685
|
time: currentTime,
|
|
686
686
|
isFirstOfPhase: false,
|
|
@@ -869,13 +869,11 @@ var PLAYER_FIELDS = [
|
|
|
869
869
|
{ name: "alignment", type: "string", label: "\u9635\u8425", description: "GOOD / EVIL" },
|
|
870
870
|
{ name: "isDead", type: "boolean", label: "\u662F\u5426\u6B7B\u4EA1" },
|
|
871
871
|
{ name: "effectiveAlive", type: "boolean", label: "\u6709\u6548\u5B58\u6D3B", description: "\u8003\u8651 retainsAbility\uFF08ALIVENESS/ALL\uFF09\u540E\u662F\u5426\u6309\u5B58\u6D3B\u5904\u7406" },
|
|
872
|
-
{ name: "diedThisTurn", type: "boolean", label: "\u672C\u56DE\u5408\u6B7B\u4EA1" },
|
|
873
|
-
{ name: "wasExecuted", type: "boolean", label: "\u66FE\u88AB\u5904\u51B3" },
|
|
874
|
-
{ name: "wasExecutedToday", type: "boolean", label: "\u4ECA\u65E5\u88AB\u5904\u51B3" },
|
|
875
872
|
{ name: "characterId", type: "string", label: "\u89D2\u8272 ID" },
|
|
876
873
|
{ name: "characterKind", type: "string", label: "\u89D2\u8272\u7C7B\u578B", description: "Townsfolk / Outsiders / Minions / Demons" },
|
|
877
874
|
{ name: "deathCause", type: "string", label: "\u6B7B\u4EA1\u539F\u56E0", description: "EXECUTION / DEMON / ABILITY / STORYTELLER / OTHER" },
|
|
878
875
|
{ name: "deathTurn", type: "number", label: "\u6B7B\u4EA1\u56DE\u5408" },
|
|
876
|
+
{ name: "deathTime", type: "string", label: "\u6B7B\u4EA1\u65F6\u6BB5", description: "day / night" },
|
|
879
877
|
{ name: "abilities", type: "string[]", label: "\u80FD\u529B ID \u5217\u8868" },
|
|
880
878
|
{ name: "reminderMarks", type: "string[]", label: "\u63D0\u793A\u7269 mark \u5217\u8868" },
|
|
881
879
|
{ name: "hasUsedDeadVote", type: "boolean", label: "\u662F\u5426\u4F7F\u7528\u8FC7\u6B7B\u4EA1\u6295\u7968" },
|
|
@@ -894,6 +892,7 @@ var NOMINATION_FIELDS = [
|
|
|
894
892
|
];
|
|
895
893
|
var CURRENT_TIMELINE_FIELDS = [
|
|
896
894
|
{ name: "turn", type: "number", label: "\u5F53\u524D\u56DE\u5408" },
|
|
895
|
+
{ name: "previousTurn", type: "number", label: "\u4E0A\u4E00\u56DE\u5408", description: "= turn - 1\uFF0C\u9996\u56DE\u5408\u4E3A -1" },
|
|
897
896
|
{ name: "phase", type: "string", label: "\u5F53\u524D\u9636\u6BB5", description: "NIGHT / DAY / DUSK / DAWN" },
|
|
898
897
|
{ name: "time", type: "string", label: "\u5F53\u524D\u65F6\u6BB5", description: "night / day" },
|
|
899
898
|
{ name: "isFirstOfPhase", type: "boolean", label: "\u662F\u5426\u672C\u9636\u6BB5\u9996\u6B21" },
|
|
@@ -1708,6 +1707,8 @@ var applyOperationToPlayers = ({
|
|
|
1708
1707
|
abilityMap,
|
|
1709
1708
|
nowTimelineIndex,
|
|
1710
1709
|
operationInTimelineIdx: record.operationInTimelineIdx,
|
|
1710
|
+
operationTurn: timelines[record.operationInTimelineIdx]?.turn ?? 0,
|
|
1711
|
+
operationTime: timelines[record.operationInTimelineIdx]?.time ?? "night",
|
|
1711
1712
|
makePlayersEffect
|
|
1712
1713
|
};
|
|
1713
1714
|
handler(context);
|
package/dist/index.mjs
CHANGED
|
@@ -463,19 +463,20 @@ var applyStatusChange = createEffectHandler("STATUS_CHANGE", ({
|
|
|
463
463
|
effect,
|
|
464
464
|
payloads,
|
|
465
465
|
makePlayersEffect,
|
|
466
|
-
|
|
466
|
+
operationTurn,
|
|
467
467
|
abilityMap,
|
|
468
|
-
operation
|
|
468
|
+
operation,
|
|
469
|
+
operationTime
|
|
469
470
|
}) => {
|
|
470
471
|
const maybeStatus = getSourceValue(effect.source, payloads);
|
|
471
472
|
if (maybeStatus === "DEAD") {
|
|
472
473
|
const ability = abilityMap.get(operation.abilityId);
|
|
473
|
-
const turn = operationInTimelineIdx >= 0 ? operationInTimelineIdx : 0;
|
|
474
474
|
const cause = effect.deathCause ?? (ability?.category === "STORYTELLER" ? "STORYTELLER" : "ABILITY");
|
|
475
475
|
makePlayersEffect.forEach((player) => {
|
|
476
476
|
player.isDead = true;
|
|
477
477
|
player.deathCause = cause;
|
|
478
|
-
player.deathTurn =
|
|
478
|
+
player.deathTurn = operationTurn;
|
|
479
|
+
player.deathTime = operationTime;
|
|
479
480
|
});
|
|
480
481
|
return;
|
|
481
482
|
}
|
|
@@ -484,6 +485,7 @@ var applyStatusChange = createEffectHandler("STATUS_CHANGE", ({
|
|
|
484
485
|
player.isDead = false;
|
|
485
486
|
delete player.deathCause;
|
|
486
487
|
delete player.deathTurn;
|
|
488
|
+
delete player.deathTime;
|
|
487
489
|
});
|
|
488
490
|
return;
|
|
489
491
|
}
|
|
@@ -506,18 +508,14 @@ var effectHandlers = {
|
|
|
506
508
|
};
|
|
507
509
|
|
|
508
510
|
// src/dsl/context.ts
|
|
509
|
-
var decoratePlayer = (player, characterMap
|
|
511
|
+
var decoratePlayer = (player, characterMap) => {
|
|
510
512
|
const isDead = Boolean(player.isDead);
|
|
511
513
|
const retainsBypass = isDead && (player.retainsAbility === "ALIVENESS" || player.retainsAbility === "ALL");
|
|
512
|
-
const wasExecuted = isDead && player.deathCause === "EXECUTION";
|
|
513
514
|
return {
|
|
514
515
|
...player,
|
|
515
516
|
characterKind: characterMap.get(player.characterId)?.kind,
|
|
516
517
|
reminderMarks: (player.reminders ?? []).map((r) => r.mark),
|
|
517
|
-
effectiveAlive: !isDead || retainsBypass
|
|
518
|
-
diedThisTurn: isDead && typeof player.deathTurn === "number" && player.deathTurn === currentTurn,
|
|
519
|
-
wasExecuted,
|
|
520
|
-
wasExecutedToday: wasExecuted && player.deathTurn === currentTurn
|
|
518
|
+
effectiveAlive: !isDead || retainsBypass
|
|
521
519
|
};
|
|
522
520
|
};
|
|
523
521
|
var isExecutionTimeline = (tl) => {
|
|
@@ -525,7 +523,7 @@ var isExecutionTimeline = (tl) => {
|
|
|
525
523
|
return (tl.operations ?? []).some((op) => op.kind === "execution");
|
|
526
524
|
};
|
|
527
525
|
var buildDslContextFromDerived = (derived, payload = []) => {
|
|
528
|
-
const players = derived.players.map((p) => decoratePlayer(p, derived.characterMap
|
|
526
|
+
const players = derived.players.map((p) => decoratePlayer(p, derived.characterMap));
|
|
529
527
|
const effector = players.find((p) => p.seat === derived.effectorSeat);
|
|
530
528
|
const aliveCount = players.filter((p) => !p.isDead).length;
|
|
531
529
|
const deadCount = players.length - aliveCount;
|
|
@@ -553,6 +551,7 @@ var buildDslContextFromDerived = (derived, payload = []) => {
|
|
|
553
551
|
},
|
|
554
552
|
currentTimeline: {
|
|
555
553
|
turn: derived.currentTurn,
|
|
554
|
+
previousTurn: derived.currentTurn - 1,
|
|
556
555
|
phase: derived.currentPhase,
|
|
557
556
|
time: derived.currentPhase === "NIGHT" ? "night" : derived.currentPhase === "DAY" ? "day" : void 0,
|
|
558
557
|
isFirstOfPhase: derived.isFirstOfPhase,
|
|
@@ -582,8 +581,8 @@ var buildDslContextFromLifetime = ({
|
|
|
582
581
|
const currentTime = nowTl?.time;
|
|
583
582
|
const currentPhase = currentTime === "night" ? "NIGHT" : currentTime === "day" ? "DAY" : "NIGHT";
|
|
584
583
|
const playersRaw = snapshotSeatMap ? [...snapshotSeatMap.values()] : [];
|
|
585
|
-
const players = playersRaw.map((p) => decoratePlayer(p, characterMap
|
|
586
|
-
const effectorDecorated = effector ? players.find((p) => p.seat === effector.seat) ?? decoratePlayer(effector, characterMap
|
|
584
|
+
const players = playersRaw.map((p) => decoratePlayer(p, characterMap));
|
|
585
|
+
const effectorDecorated = effector ? players.find((p) => p.seat === effector.seat) ?? decoratePlayer(effector, characterMap) : void 0;
|
|
587
586
|
const todayOps = timelines.filter((tl) => tl.turn === currentTurn && tl.time === "day").flatMap((tl) => tl.operations ?? []);
|
|
588
587
|
const tonightOps = timelines.filter((tl) => tl.turn === currentTurn && tl.time === "night").flatMap((tl) => tl.operations ?? []);
|
|
589
588
|
const yesterdayDayOps = timelines.filter((tl) => tl.turn === currentTurn - 1 && tl.time === "day").flatMap((tl) => tl.operations ?? []);
|
|
@@ -625,6 +624,7 @@ var buildDslContextFromLifetime = ({
|
|
|
625
624
|
},
|
|
626
625
|
currentTimeline: {
|
|
627
626
|
turn: currentTurn,
|
|
627
|
+
previousTurn: currentTurn - 1,
|
|
628
628
|
phase: currentPhase,
|
|
629
629
|
time: currentTime,
|
|
630
630
|
isFirstOfPhase: false,
|
|
@@ -813,13 +813,11 @@ var PLAYER_FIELDS = [
|
|
|
813
813
|
{ name: "alignment", type: "string", label: "\u9635\u8425", description: "GOOD / EVIL" },
|
|
814
814
|
{ name: "isDead", type: "boolean", label: "\u662F\u5426\u6B7B\u4EA1" },
|
|
815
815
|
{ name: "effectiveAlive", type: "boolean", label: "\u6709\u6548\u5B58\u6D3B", description: "\u8003\u8651 retainsAbility\uFF08ALIVENESS/ALL\uFF09\u540E\u662F\u5426\u6309\u5B58\u6D3B\u5904\u7406" },
|
|
816
|
-
{ name: "diedThisTurn", type: "boolean", label: "\u672C\u56DE\u5408\u6B7B\u4EA1" },
|
|
817
|
-
{ name: "wasExecuted", type: "boolean", label: "\u66FE\u88AB\u5904\u51B3" },
|
|
818
|
-
{ name: "wasExecutedToday", type: "boolean", label: "\u4ECA\u65E5\u88AB\u5904\u51B3" },
|
|
819
816
|
{ name: "characterId", type: "string", label: "\u89D2\u8272 ID" },
|
|
820
817
|
{ name: "characterKind", type: "string", label: "\u89D2\u8272\u7C7B\u578B", description: "Townsfolk / Outsiders / Minions / Demons" },
|
|
821
818
|
{ name: "deathCause", type: "string", label: "\u6B7B\u4EA1\u539F\u56E0", description: "EXECUTION / DEMON / ABILITY / STORYTELLER / OTHER" },
|
|
822
819
|
{ name: "deathTurn", type: "number", label: "\u6B7B\u4EA1\u56DE\u5408" },
|
|
820
|
+
{ name: "deathTime", type: "string", label: "\u6B7B\u4EA1\u65F6\u6BB5", description: "day / night" },
|
|
823
821
|
{ name: "abilities", type: "string[]", label: "\u80FD\u529B ID \u5217\u8868" },
|
|
824
822
|
{ name: "reminderMarks", type: "string[]", label: "\u63D0\u793A\u7269 mark \u5217\u8868" },
|
|
825
823
|
{ name: "hasUsedDeadVote", type: "boolean", label: "\u662F\u5426\u4F7F\u7528\u8FC7\u6B7B\u4EA1\u6295\u7968" },
|
|
@@ -838,6 +836,7 @@ var NOMINATION_FIELDS = [
|
|
|
838
836
|
];
|
|
839
837
|
var CURRENT_TIMELINE_FIELDS = [
|
|
840
838
|
{ name: "turn", type: "number", label: "\u5F53\u524D\u56DE\u5408" },
|
|
839
|
+
{ name: "previousTurn", type: "number", label: "\u4E0A\u4E00\u56DE\u5408", description: "= turn - 1\uFF0C\u9996\u56DE\u5408\u4E3A -1" },
|
|
841
840
|
{ name: "phase", type: "string", label: "\u5F53\u524D\u9636\u6BB5", description: "NIGHT / DAY / DUSK / DAWN" },
|
|
842
841
|
{ name: "time", type: "string", label: "\u5F53\u524D\u65F6\u6BB5", description: "night / day" },
|
|
843
842
|
{ name: "isFirstOfPhase", type: "boolean", label: "\u662F\u5426\u672C\u9636\u6BB5\u9996\u6B21" },
|
|
@@ -1652,6 +1651,8 @@ var applyOperationToPlayers = ({
|
|
|
1652
1651
|
abilityMap,
|
|
1653
1652
|
nowTimelineIndex,
|
|
1654
1653
|
operationInTimelineIdx: record.operationInTimelineIdx,
|
|
1654
|
+
operationTurn: timelines[record.operationInTimelineIdx]?.turn ?? 0,
|
|
1655
|
+
operationTime: timelines[record.operationInTimelineIdx]?.time ?? "night",
|
|
1655
1656
|
makePlayersEffect
|
|
1656
1657
|
};
|
|
1657
1658
|
handler(context);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bct-app/game-engine",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.21",
|
|
4
4
|
"description": "Game engine utilities for BCT",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"access": "public"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@bct-app/game-model": "0.1.
|
|
33
|
+
"@bct-app/game-model": "0.1.14"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
36
|
"@vitest/ui": "^4.1.3",
|