valtech-components 4.0.625 → 4.0.627
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/esm2022/lib/components/organisms/mini-games/christianity-rules.mjs +120 -8
- package/esm2022/lib/components/organisms/mini-games/types.mjs +1 -1
- package/esm2022/lib/version.mjs +2 -2
- package/fesm2022/valtech-components.mjs +120 -8
- package/fesm2022/valtech-components.mjs.map +1 -1
- package/lib/components/organisms/mini-games/chessimals-game.component.d.ts +1 -1
- package/lib/components/organisms/mini-games/types.d.ts +42 -1
- package/lib/version.d.ts +1 -1
- package/package.json +1 -1
|
@@ -59,7 +59,7 @@ import fixWebmDuration from 'fix-webm-duration';
|
|
|
59
59
|
* Current version of valtech-components.
|
|
60
60
|
* This is automatically updated during the publish process.
|
|
61
61
|
*/
|
|
62
|
-
const VERSION = '4.0.
|
|
62
|
+
const VERSION = '4.0.627';
|
|
63
63
|
|
|
64
64
|
// Control de estado de refresco (singleton a nivel de módulo)
|
|
65
65
|
let isRefreshing = false;
|
|
@@ -74432,7 +74432,7 @@ function playCardFromHand(game, seat, card, options = {}) {
|
|
|
74432
74432
|
spentOfferings = card.cost ?? 0;
|
|
74433
74433
|
spendOfferings(player, spentOfferings);
|
|
74434
74434
|
const life = card.life ?? 1;
|
|
74435
|
-
|
|
74435
|
+
const newChar = {
|
|
74436
74436
|
instanceId: `${seat.toLowerCase()}_${next.revision + 1}_${player.battleZone.length}`,
|
|
74437
74437
|
cardId: card.id,
|
|
74438
74438
|
name: displayName,
|
|
@@ -74443,7 +74443,11 @@ function playCardFromHand(game, seat, card, options = {}) {
|
|
|
74443
74443
|
currentHp: life,
|
|
74444
74444
|
maxHp: life,
|
|
74445
74445
|
canAttack: false,
|
|
74446
|
-
}
|
|
74446
|
+
};
|
|
74447
|
+
bakeEffects(newChar, card.effects ?? []);
|
|
74448
|
+
player.battleZone.push(newChar);
|
|
74449
|
+
fireEffects(next, newChar, 'on_enter', seat);
|
|
74450
|
+
fireEffects(next, newChar, 'passive', seat);
|
|
74447
74451
|
player.battleZone.sort((left, right) => (left.slot ?? 0) - (right.slot ?? 0));
|
|
74448
74452
|
}
|
|
74449
74453
|
else if (card.type === 'tool') {
|
|
@@ -74538,8 +74542,10 @@ function resolveAttackLeader(game, attackerSeat, attackerInstanceId, messages) {
|
|
|
74538
74542
|
const attacker = next.players[attackerSeat].battleZone.find(card => card.instanceId === attackerInstanceId);
|
|
74539
74543
|
if (!attacker || !attacker.canAttack)
|
|
74540
74544
|
return { game, attacked: false, attackerDamage: 0, targetDamage: 0, log: [] };
|
|
74541
|
-
|
|
74545
|
+
fireEffects(next, attacker, 'on_attack', attackerSeat, { targeting: 'leader' });
|
|
74546
|
+
const damage = attacker.attack + (attacker.combatAttackBuff ?? 0);
|
|
74542
74547
|
next.players[defenderSeat].leaderHp = Math.max(0, next.players[defenderSeat].leaderHp - damage);
|
|
74548
|
+
attacker.combatAttackBuff = 0;
|
|
74543
74549
|
attacker.canAttack = false;
|
|
74544
74550
|
const log = [
|
|
74545
74551
|
`${attacker.name} ${attackerSeat === 'P1' ? messages.attacksOpponentLeader : messages.attacksYourLeader}`,
|
|
@@ -74559,8 +74565,14 @@ function resolveAttackCharacter(game, attackerSeat, attackerInstanceId, targetIn
|
|
|
74559
74565
|
if (!attacker || !target || !attacker.canAttack) {
|
|
74560
74566
|
return { game, attacked: false, attackerDamage: 0, targetDamage: 0, log: [] };
|
|
74561
74567
|
}
|
|
74562
|
-
|
|
74563
|
-
|
|
74568
|
+
fireEffects(next, attacker, 'on_attack', attackerSeat, { targeting: 'character' }, target);
|
|
74569
|
+
fireEffects(next, target, 'on_defend', defenderSeat, { targeting: 'character' }, attacker);
|
|
74570
|
+
const attackerTotal = attacker.attack + (attacker.combatAttackBuff ?? 0);
|
|
74571
|
+
const targetTotal = target.attack + (target.combatAttackBuff ?? 0);
|
|
74572
|
+
target.currentHp -= attackerTotal;
|
|
74573
|
+
attacker.currentHp -= targetTotal;
|
|
74574
|
+
attacker.combatAttackBuff = 0;
|
|
74575
|
+
target.combatAttackBuff = 0;
|
|
74564
74576
|
attacker.canAttack = false;
|
|
74565
74577
|
cleanupDestroyed(next.players[attackerSeat], next);
|
|
74566
74578
|
cleanupDestroyed(next.players[defenderSeat], next);
|
|
@@ -74571,8 +74583,8 @@ function resolveAttackCharacter(game, attackerSeat, attackerInstanceId, targetIn
|
|
|
74571
74583
|
return {
|
|
74572
74584
|
game: next,
|
|
74573
74585
|
attacked: true,
|
|
74574
|
-
attackerDamage:
|
|
74575
|
-
targetDamage:
|
|
74586
|
+
attackerDamage: targetTotal,
|
|
74587
|
+
targetDamage: attackerTotal,
|
|
74576
74588
|
log,
|
|
74577
74589
|
};
|
|
74578
74590
|
}
|
|
@@ -74625,6 +74637,9 @@ function cleanupDestroyed(player, game) {
|
|
|
74625
74637
|
const destroyed = player.battleZone.filter(card => card.currentHp <= 0);
|
|
74626
74638
|
if (!destroyed.length)
|
|
74627
74639
|
return;
|
|
74640
|
+
for (const ch of destroyed) {
|
|
74641
|
+
fireEffects(game, ch, 'on_death', ch.owner);
|
|
74642
|
+
}
|
|
74628
74643
|
game.historyZone.push(...destroyed.map(card => card.cardId));
|
|
74629
74644
|
player.battleZone = player.battleZone.filter(card => card.currentHp > 0);
|
|
74630
74645
|
}
|
|
@@ -74651,6 +74666,102 @@ function offeringAbilityReserveGain(abilityText, fallbackValue) {
|
|
|
74651
74666
|
function opponentSeat(seat) {
|
|
74652
74667
|
return seat === 'P1' ? 'P2' : 'P1';
|
|
74653
74668
|
}
|
|
74669
|
+
function checkCondition(condition, ctx) {
|
|
74670
|
+
if (!condition)
|
|
74671
|
+
return true;
|
|
74672
|
+
return condition.targeting === ctx.targeting;
|
|
74673
|
+
}
|
|
74674
|
+
function applyMutationToCharacter(ch, effect) {
|
|
74675
|
+
const mut = effect.mutation;
|
|
74676
|
+
const duration = effect.duration ?? 'permanent';
|
|
74677
|
+
switch (mut.type) {
|
|
74678
|
+
case 'buff_attack':
|
|
74679
|
+
if (duration === 'combat') {
|
|
74680
|
+
ch.combatAttackBuff = (ch.combatAttackBuff ?? 0) + mut.amount;
|
|
74681
|
+
}
|
|
74682
|
+
else {
|
|
74683
|
+
ch.attack += mut.amount;
|
|
74684
|
+
}
|
|
74685
|
+
break;
|
|
74686
|
+
case 'buff_life':
|
|
74687
|
+
ch.currentHp += mut.amount;
|
|
74688
|
+
ch.maxHp += mut.amount;
|
|
74689
|
+
break;
|
|
74690
|
+
case 'deal_damage':
|
|
74691
|
+
ch.currentHp = Math.max(0, ch.currentHp - mut.amount);
|
|
74692
|
+
break;
|
|
74693
|
+
case 'restore_hp':
|
|
74694
|
+
ch.currentHp = Math.min(ch.maxHp, ch.currentHp + mut.amount);
|
|
74695
|
+
break;
|
|
74696
|
+
case 'destroy':
|
|
74697
|
+
ch.currentHp = 0;
|
|
74698
|
+
break;
|
|
74699
|
+
}
|
|
74700
|
+
}
|
|
74701
|
+
function applyEffect(game, effect, source, combatOpponent, seat) {
|
|
74702
|
+
const { mutation: mut, target } = effect;
|
|
74703
|
+
const opp = opponentSeat(seat);
|
|
74704
|
+
switch (target) {
|
|
74705
|
+
case 'self':
|
|
74706
|
+
applyMutationToCharacter(source, effect);
|
|
74707
|
+
break;
|
|
74708
|
+
case 'combat_opponent':
|
|
74709
|
+
if (combatOpponent)
|
|
74710
|
+
applyMutationToCharacter(combatOpponent, effect);
|
|
74711
|
+
break;
|
|
74712
|
+
case 'all_friendly':
|
|
74713
|
+
for (const ch of game.players[seat].battleZone)
|
|
74714
|
+
applyMutationToCharacter(ch, effect);
|
|
74715
|
+
break;
|
|
74716
|
+
case 'all_enemy':
|
|
74717
|
+
for (const ch of game.players[opp].battleZone)
|
|
74718
|
+
applyMutationToCharacter(ch, effect);
|
|
74719
|
+
break;
|
|
74720
|
+
case 'opponent_leader':
|
|
74721
|
+
case 'own_leader': {
|
|
74722
|
+
const ls = target === 'opponent_leader' ? opp : seat;
|
|
74723
|
+
if (mut.type === 'deal_damage') {
|
|
74724
|
+
game.players[ls].leaderHp = Math.max(0, game.players[ls].leaderHp - mut.amount);
|
|
74725
|
+
}
|
|
74726
|
+
else if (mut.type === 'restore_hp') {
|
|
74727
|
+
game.players[ls].leaderHp = Math.min(game.players[ls].leaderMaxHp, game.players[ls].leaderHp + mut.amount);
|
|
74728
|
+
}
|
|
74729
|
+
break;
|
|
74730
|
+
}
|
|
74731
|
+
}
|
|
74732
|
+
// game-level mutations that bypass the character switch
|
|
74733
|
+
if (mut.type === 'draw_card') {
|
|
74734
|
+
for (let i = 0; i < mut.amount; i++)
|
|
74735
|
+
drawCardFor(game, seat);
|
|
74736
|
+
}
|
|
74737
|
+
else if (mut.type === 'discard_card') {
|
|
74738
|
+
const tSeat = mut.who === 'opponent' ? opp : seat;
|
|
74739
|
+
const hand = game.players[tSeat].hand ?? [];
|
|
74740
|
+
let seed = game.revision * 31 + game.turnCount * 7;
|
|
74741
|
+
for (let i = 0; i < Math.min(mut.amount, hand.length); i++) {
|
|
74742
|
+
seed = (seed * 1664525 + 1013904223) & 0xffffffff;
|
|
74743
|
+
const idx = Math.abs(seed) % hand.length;
|
|
74744
|
+
game.historyZone.push(hand.splice(idx, 1)[0]);
|
|
74745
|
+
}
|
|
74746
|
+
game.players[tSeat].hand = hand;
|
|
74747
|
+
}
|
|
74748
|
+
else if (mut.type === 'gain_offerings') {
|
|
74749
|
+
game.players[seat].temporaryOfferingReserve =
|
|
74750
|
+
(game.players[seat].temporaryOfferingReserve ?? 0) + mut.amount;
|
|
74751
|
+
}
|
|
74752
|
+
}
|
|
74753
|
+
function fireEffects(game, source, trigger, seat, ctx = {}, combatOpponent = null) {
|
|
74754
|
+
for (const effect of source.effects ?? []) {
|
|
74755
|
+
if (effect.trigger !== trigger)
|
|
74756
|
+
continue;
|
|
74757
|
+
if (!checkCondition(effect.condition, ctx))
|
|
74758
|
+
continue;
|
|
74759
|
+
applyEffect(game, effect, source, combatOpponent, seat);
|
|
74760
|
+
}
|
|
74761
|
+
}
|
|
74762
|
+
function bakeEffects(instance, effects) {
|
|
74763
|
+
instance.effects = [...(instance.effects ?? []), ...effects];
|
|
74764
|
+
}
|
|
74654
74765
|
// --- Tool equip passives (H8) ---
|
|
74655
74766
|
function applyToolPassives(ch, card) {
|
|
74656
74767
|
const text = card.abilities?.[0]?.text ?? '';
|
|
@@ -74667,6 +74778,7 @@ function applyToolPassives(ch, card) {
|
|
|
74667
74778
|
if (lower.includes('puede atacar el turno en que entra')) {
|
|
74668
74779
|
ch.canAttack = true;
|
|
74669
74780
|
}
|
|
74781
|
+
bakeEffects(ch, card.effects ?? []);
|
|
74670
74782
|
}
|
|
74671
74783
|
// --- Effect resolution (H7) ---
|
|
74672
74784
|
function resolveCardEffect(game, card, seat) {
|