Skip to content

Commit

Permalink
Fix Composite Yumi + Force of the River
Browse files Browse the repository at this point in the history
  • Loading branch information
lsocrate committed Jan 11, 2024
1 parent 419d7af commit b3725a4
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 12 deletions.
1 change: 1 addition & 0 deletions server/game/Constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,7 @@ export enum PlayTypes {
export enum EventNames {
OnMoveFate = 'onMoveFate',
OnBeginRound = 'onBeginRound',
OnCreateTokenCharacter = 'onCreateTokenCharacter',
OnCharacterEntersPlay = 'onCharacterEntersPlay',
OnInitiateAbilityEffects = 'onInitiateAbilityEffects',
OnCardAbilityInitiated = 'onCardAbilityInitiated',
Expand Down
10 changes: 7 additions & 3 deletions server/game/GameActions/CreateTokenAction.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
import type { AbilityContext } from '../AbilityContext';
import type BaseCard from '../basecard';
import { CardTypes, Durations, Locations } from '../Constants';
import { CardTypes, Durations, EventNames, Locations } from '../Constants';
import Effects from '../effects';
import { type CardActionProperties, CardGameAction } from './CardGameAction';

export interface CreateTokenProperties extends CardActionProperties {
atHome?: boolean;
}

export class CreateTokenAction extends CardGameAction {
export class CreateTokenAction extends CardGameAction<CreateTokenProperties> {
name = 'createToken';
effect = 'create a token';
eventName = EventNames.OnCreateTokenCharacter;
targetType = [CardTypes.Character, CardTypes.Holding, CardTypes.Event];
defaultProperties: CreateTokenProperties = { atHome: false };

Expand All @@ -24,7 +25,7 @@ export class CreateTokenAction extends CardGameAction {
}

eventHandler(event, additionalProperties = {}): void {
let { atHome } = this.getProperties(event.context, additionalProperties) as CreateTokenProperties;
let { atHome } = this.getProperties(event.context, additionalProperties);
let context = event.context;
let card = event.card;
let token = context.game.createToken(card);
Expand All @@ -39,6 +40,7 @@ export class CreateTokenAction extends CardGameAction {
context.game.currentConflict.addDefender(token);
}
}

context.game.actions
.cardLastingEffect({
duration: Durations.UntilEndOfPhase,
Expand All @@ -52,5 +54,7 @@ export class CreateTokenAction extends CardGameAction {
})
})
.resolve(token, context);

context.game.raiseEvent(EventNames.OnCreateTokenCharacter, { tokenCharacter: token });
}
}
4 changes: 2 additions & 2 deletions server/game/cards/04.4-TEaF/ForceOfTheRiver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ export default class ForceOfTheRiver extends DrawCard {
effect: 'summon {1}!',
effectArgs: {
id: 'spirit-of-the-river',
label: 'Sprits of the River',
name: 'Sprits of the River',
label: 'Spirits of the River',
name: 'Spirits of the River',
facedown: false,
type: CardTypes.Character
},
Expand Down
9 changes: 5 additions & 4 deletions server/game/cards/20-Core2/Unicorn/CompositeYumi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@ export default class CompositeYumi extends DrawCard {
this.reaction({
title: 'Give attached character +1/+0',
when: {
onMoveToConflict: (event, context) => Boolean(context.source.parent),
onSendHome: (event, context) => Boolean(context.source.parent),
onCharacterEntersPlay: (event, context) =>
Boolean(context.source.parent) && context.game.isDuringConflict()
onMoveToConflict: (event, context) => context.source.parent,
onSendHome: (event, context) => context.source.parent,
onCharacterEntersPlay: (event, context) => context.source.parent && context.game.isDuringConflict(),
onCreateTokenCharacter: (event, context) =>
context.source.parent && event.tokenCharacter?.isParticipating()
},
gameAction: AbilityDsl.actions.cardLastingEffect((context) => ({
target: context.source.parent,
Expand Down
43 changes: 40 additions & 3 deletions test/server/cards/20-Core2/Unicorn/CompositeYumi.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ describe('Composite Yumi', function () {
this.setupTest({
phase: 'conflict',
player1: {
inPlay: ['wandering-ronin', 'eager-scout'],
dynastyDeck: ['favorable-ground'],
hand: ['composite-yumi', 'steward-of-law']
inPlay: ['wandering-ronin', 'eager-scout', 'master-of-the-swift-waves'],
dynastyDeck: ['favorable-ground', 'hida-kisada', 'imperial-storehouse'],
hand: ['composite-yumi', 'steward-of-law', 'force-of-the-river'],
provinces: ['manicured-garden']
},
player2: {
inPlay: ['shinjo-outrider'],
Expand All @@ -16,12 +17,22 @@ describe('Composite Yumi', function () {
this.fg = this.player1.placeCardInProvince('favorable-ground', 'province 1');
this.wanderingRonin = this.player1.findCardByName('wandering-ronin');
this.scout = this.player1.findCardByName('eager-scout');
this.masterOfTheSwiftWaves = this.player1.findCardByName('master-of-the-swift-waves');
this.stewardOfLaw = this.player1.findCardByName('steward-of-law');
this.compositeYumi = this.player1.findCardByName('composite-yumi');
this.forceOfTheRiver = this.player1.findCardByName('force-of-the-river');

this.shinjoOutrider = this.player2.findCardByName('shinjo-outrider');
this.stoicGunso = this.player2.findCardByName('stoic-gunso');

this.garden = this.player1.findCardByName('manicured-garden');
this.kisada = this.player1.findCardByName('hida-kisada');
this.storehouse = this.player1.findCardByName('imperial-storehouse');
this.player1.moveCard(this.storehouse, this.garden.location);
this.player1.moveCard(this.kisada, this.garden.location);
this.kisada.facedown = true;
this.storehouse.facedown = true;

this.player1.playAttachment(this.compositeYumi, this.wanderingRonin);

this.noMoreActions();
Expand Down Expand Up @@ -159,5 +170,31 @@ describe('Composite Yumi', function () {
this.player1.clickCard(this.compositeYumi);
expect(this.wanderingRonin.getMilitarySkill()).toBe(2 + 1 + 4);
});

it('comboes with Force of the River', function () {
this.initiateConflict({
attackers: [this.wanderingRonin],
defenders: []
});
this.player2.pass();
this.player1.clickCard(this.forceOfTheRiver);
this.player1.clickCard(this.masterOfTheSwiftWaves);
this.player2.pass();

this.player1.clickCard(this.forceOfTheRiver);

expect(this.player1).toHavePrompt('Any reactions?');
expect(this.player1).toBeAbleToSelect(this.compositeYumi);
this.player1.clickCard(this.compositeYumi);
expect(this.getChatLogs(3)).toContain('player1 uses Composite Yumi to give +1military to Wandering Ronin');

expect(this.player1).toHavePrompt('Any reactions?');
expect(this.player1).toBeAbleToSelect(this.compositeYumi);
this.player1.clickCard(this.compositeYumi);
expect(this.getChatLogs(3)).toContain('player1 uses Composite Yumi to give +1military to Wandering Ronin');

expect(this.player1).toHavePrompt('Any reactions?');
expect(this.player1).toBeAbleToSelect(this.compositeYumi);
});
});
});

0 comments on commit b3725a4

Please sign in to comment.