Skip to content
This repository has been archived by the owner on Jan 29, 2020. It is now read-only.

Merge dev into seekers-of-wisdom #3887

Merged
merged 125 commits into from
Jan 19, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
125 commits
Select commit Hold shift + click to select a range
dde9101
Update .travis.yml
jeremylarner Nov 6, 2019
c68fc74
Merge pull request #3642 from jeremylarner/develop3
jeremylarner Nov 6, 2019
c11200a
aCF - Petal Village Estate (#3605)
marcsoiferman-cm Nov 10, 2019
2a4c400
aCF - By Any Means (#3621)
marcsoiferman-cm Nov 10, 2019
8816d77
aCF - Henshin mysteries (#3586)
Matthew-Griffith Nov 10, 2019
d2cbe5a
aCF - Asako Takahiro (#3590)
Matthew-Griffith Nov 10, 2019
f29b64d
aCF - Fan of Command (#3614)
marcsoiferman-cm Nov 10, 2019
4a6f99f
aCF - Palace Guard (#3607)
marcsoiferman-cm Nov 10, 2019
fa7fd74
aCF - Strategic Weakpoint (#3608)
marcsoiferman-cm Nov 10, 2019
d94a40f
acf - Quarrelsome Youth (#3612)
marcsoiferman-cm Nov 10, 2019
205918a
aCF - Outflank (#3613)
marcsoiferman-cm Nov 10, 2019
c6f9ebf
aCF - Smugglers cove (#3584)
Matthew-Griffith Nov 11, 2019
7214974
aCF - Unified company (#3588)
Matthew-Griffith Nov 11, 2019
2eb4c90
add folder structure
The-Outcast Nov 13, 2019
06c25be
aCF - Deduction (#3625)
marcsoiferman-cm Nov 19, 2019
664f9e7
Merge pull request #3694 from gryffon/develop
The-Outcast Nov 19, 2019
ac3133a
Merge pull request #3695 from gryffon/develop
The-Outcast Nov 19, 2019
3ca7b86
DoR - Hida O-Ushi (#3690)
marcsoiferman-cm Nov 22, 2019
42e1835
Merge develop into DoR (#3715)
jeremylarner Nov 22, 2019
75faccd
DoR - Moto Eviscerator (#3712)
marcsoiferman-cm Nov 22, 2019
f6726fa
DoR - Reinforced Plate (#3711)
marcsoiferman-cm Nov 22, 2019
cfbf08c
DoR - Matsu Agetoki (#3705)
marcsoiferman-cm Nov 22, 2019
fafd280
DoR - Purifier Apprentice (#3704)
marcsoiferman-cm Nov 22, 2019
32df205
DoR - Shinjo Yasamura (#3703)
marcsoiferman-cm Nov 22, 2019
c5d5a73
DoR - Seventh Tower (#3702)
marcsoiferman-cm Nov 22, 2019
9fa9b58
DoR - Subterranean Guile (#3692)
marcsoiferman-cm Nov 22, 2019
624a2cc
DoR - Siege Warfare (#3691)
marcsoiferman-cm Nov 22, 2019
d8e6abf
DoR - River of the Last Stand (#3689)
marcsoiferman-cm Nov 22, 2019
c87608a
DoR - Fruitful Respite (#3713)
marcsoiferman-cm Nov 22, 2019
576fda0
DoR - Watchtower of Valor (#3687)
marcsoiferman-cm Nov 22, 2019
b735a6f
DoR - Slovenly Scavenger (#3721)
marcsoiferman-cm Nov 24, 2019
23086f2
DoR - Kansen Haunt (#3722)
marcsoiferman-cm Nov 24, 2019
7ecd837
aCF - Frontline Engineer (#3627)
marcsoiferman-cm Nov 24, 2019
766561d
Updated the unified company test to hopefully pass on the server (pas…
marcsoiferman-cm Nov 28, 2019
a7b28a4
Merge develop into dor (#3733)
jeremylarner Nov 29, 2019
889ad8e
Merge develop into acf (#3734)
jeremylarner Nov 29, 2019
6e07f99
This fixes a gamenode crash during the regroup stage if you don't hav…
Nov 30, 2019
97e9b95
Linting cleanup
Nov 30, 2019
3a00b65
aCF - Shukujo (#3604)
marcsoiferman-cm Dec 1, 2019
3eced44
aCF - Army of the Rising Wave (#3616)
marcsoiferman-cm Dec 1, 2019
7a0323b
aCF - Erudite Prestige (#3683)
marcsoiferman-cm Dec 1, 2019
073d4f1
aCF - Daidoji Kageyu (#3728)
marcsoiferman-cm Dec 1, 2019
220ea81
aCF - Keeper of Secret Names (#3738)
marcsoiferman-cm Dec 1, 2019
d2375e1
aCF - Shiro kitsuki (#3597)
Matthew-Griffith Dec 1, 2019
aee7d4a
DoR - Daidoji Netsu (#3736)
marcsoiferman-cm Dec 1, 2019
46c06f4
DoR - Desolation (#3723)
marcsoiferman-cm Dec 1, 2019
9c72a74
DoR - Shadowlands Hunter (#3739)
marcsoiferman-cm Dec 1, 2019
9a3d76f
DoR - Yogo Asami (#3730)
marcsoiferman-cm Dec 1, 2019
c026d0c
DoR - Kyuden Hida (#3686)
marcsoiferman-cm Dec 1, 2019
b4dde01
DoR - Northern Curtain Wall (#3688)
marcsoiferman-cm Dec 1, 2019
ab203bc
DoR - Isawa Eju (#3725)
marcsoiferman-cm Dec 1, 2019
fb9788a
DoR - Unyielding Sensei (#3740)
marcsoiferman-cm Dec 1, 2019
823b07a
DoR - Hida Sukune (#3724)
marcsoiferman-cm Dec 1, 2019
c5e1a20
aCF - Keeper of Secret Names updated tests to add test for blanked pr…
marcsoiferman-cm Dec 1, 2019
d9db475
DoR - Kaiu Forges (#3731)
marcsoiferman-cm Dec 2, 2019
5767635
DoR - The Strength of the Mountain (#3743)
marcsoiferman-cm Dec 2, 2019
b278541
DoR - Kaiu Siege Force (#3726)
marcsoiferman-cm Dec 2, 2019
9605d73
DoR - Third Whisker Warrens (#3735)
marcsoiferman-cm Dec 2, 2019
bb93a84
DoR - Agasha Hiyori (#3727)
marcsoiferman-cm Dec 2, 2019
09feca3
DoR - Favorable Dealbroker (#3729)
marcsoiferman-cm Dec 2, 2019
84f1dfa
DoR - Kuni Wastelands (#3741)
marcsoiferman-cm Dec 2, 2019
0c8184e
Update 5ringsdb data
The-Outcast Dec 2, 2019
13c790e
Tests and implementation for Moto Outrider
marcsoiferman-cm Dec 3, 2019
174f4c6
Merge pull request #3747 from marcsoiferman-cm/shojus-duty-moto-outrider
jeremylarner Dec 3, 2019
cbee3bf
Merge pull request #3737 from marcsoiferman-cm/dev-single-player-bugfix
jeremylarner Dec 6, 2019
edf1f56
Merge pull request #3770 from jeremylarner/develop5
jeremylarner Dec 6, 2019
0d1dec4
SD - Bayushi Shoju (#3767)
marcsoiferman-cm Dec 6, 2019
05bed00
DoR - Kaiu Shihobu (Using new Child Cards) (#3768)
marcsoiferman-cm Dec 7, 2019
5f148df
Merge branch 'develop' into dor
The-Outcast Dec 7, 2019
628ea19
Merge branch 'dor' of https://github.com/gryffon/ringteki into dor
The-Outcast Dec 7, 2019
1867e3b
Merge branch 'develop' into dor
The-Outcast Dec 7, 2019
8e2e857
Merge pull request #3772 from gryffon/dor
The-Outcast Dec 7, 2019
ba5b7b4
SD - Persuasive Counselor (#3771)
marcsoiferman-cm Dec 7, 2019
3a8ca2b
SD - Student of Esoterica (#3769)
marcsoiferman-cm Dec 7, 2019
514c6a8
Implementation and tests for Chrysanthemum Steward
The-Outcast Dec 7, 2019
8e8eb83
SD - Gallant Quartermaster (#3778)
marcsoiferman-cm Dec 8, 2019
adec2b3
ACF - Current of the Beryt (#3776)
jeremylarner Dec 8, 2019
32f57cf
SD - Cloak of Night (#3779)
marcsoiferman-cm Dec 8, 2019
0f094ae
SD - Daidoji Harrier (#3782)
marcsoiferman-cm Dec 8, 2019
1d1fa00
ACF - Withstand the Darkness Take 2 (#3745)
marcsoiferman-cm Dec 8, 2019
88e4fc1
Merge branch 'develop' into acf
The-Outcast Dec 8, 2019
c7e7e1f
SD - Golden Plains Raider (#3783)
marcsoiferman-cm Dec 8, 2019
3239485
SD - Hero of Three Trees (#3784)
marcsoiferman-cm Dec 8, 2019
cbf8a51
Merge pull request #3788 from gryffon/acf
The-Outcast Dec 8, 2019
cf539fe
SD - Hitsu-Do Disciple #3785
marcsoiferman-cm Dec 8, 2019
9db4906
SD - In Service to My Lord (#3786)
marcsoiferman-cm Dec 8, 2019
af06066
SD - Mantra of Air (#3787)
marcsoiferman-cm Dec 8, 2019
9f44960
SD - Yasuki Hatsu (#3789)
marcsoiferman-cm Dec 8, 2019
145f7b5
SD - Togashi Ichi (#3790)
marcsoiferman-cm Dec 8, 2019
3630e19
SD - Castigated (#3793)
marcsoiferman-cm Dec 9, 2019
a102331
SD - Kakita's Final Stance (#3791)
marcsoiferman-cm Dec 9, 2019
ab51d59
SD - Root Out Heresy (#3792)
marcsoiferman-cm Dec 9, 2019
6ead51c
Merge pull request #3775 from The-Outcast/card/SD/Chrysanthemum_Steward
marcsoiferman-cm Dec 9, 2019
6dca84c
SD - Inferno Guard Invoker (#3774)
The-Outcast Dec 9, 2019
be263d3
Bugfixes for Into the Forbidden City and Ardent Omoidasu (#3795)
jeremylarner Dec 11, 2019
606bb7e
Kuni Wasteland fixes (#3797)
jeremylarner Dec 11, 2019
6eae0de
The Perfect Gift doesn't shuffle the conflict deck (#3744)
The-Outcast Dec 12, 2019
46f51b1
Shiro Kitsuki fails to check all other cards played after the first (…
The-Outcast Dec 12, 2019
75f555d
Keeper of Secret Names couldn't trigger if the province was already t…
The-Outcast Dec 12, 2019
0ecf7d1
Added a "Take nothing" prompt. (#3800)
marcsoiferman-cm Dec 13, 2019
40b6325
Added null checks to Seventh Tower (#3829)
marcsoiferman-cm Dec 16, 2019
11050e3
Kyuden Ikoma could incorrectly target attachments. (#3844)
marcsoiferman-cm Dec 21, 2019
210c409
Add Void Fist test (#3848)
The-Outcast Dec 22, 2019
ceade67
Manual actions and RFG drag/drop (#3853)
The-Outcast Dec 26, 2019
92993a8
RRG v12 banned/restricted list updates (#3851)
jeremylarner Dec 30, 2019
0df25f4
Fix Regal Bearing message (#3859)
The-Outcast Dec 30, 2019
6d7d782
FAQ v12 card errata (#3852)
jeremylarner Dec 30, 2019
d36c2f3
Merge branch 'develop' into shojus-duty
The-Outcast Dec 30, 2019
4d10b23
Fix tests around AtW
The-Outcast Dec 30, 2019
f890afd
Merge pull request #3861 from gryffon/shojus-duty
The-Outcast Dec 30, 2019
333d275
Ring resolving rules updated (#3865)
The-Outcast Dec 30, 2019
4be07cd
Fix the max 1 per conflict clause on Regal Bearing (#3866)
The-Outcast Dec 31, 2019
ee07ec3
Change duels in accordance with v12 RRG (#3868)
jeremylarner Dec 31, 2019
bc09cee
Remove Regroup Phase (#3870)
marcsoiferman-cm Dec 31, 2019
b5c087b
Apply new RRG changes around discard pile order (#3867)
The-Outcast Jan 1, 2020
e72fcff
Fixed Kageyu's ability title (#3872)
marcsoiferman-cm Jan 1, 2020
5d52cf8
Add FFG official Favor images
gryffon Jan 8, 2020
0d900bf
Use new *-favor.jpg files instead of old scanned pngs
gryffon Jan 8, 2020
50cc07d
Add Cancel Prompt button to HandlerMenuPrompt (#3883)
jeremylarner Jan 10, 2020
bf9f643
Tactical Ingenuity bugfix (#3882)
jeremylarner Jan 10, 2020
d7fb5be
Update FeastOrFamine.js (#3879)
IFightDragons Jan 11, 2020
0e3f82f
Kyuden Isawa bugfix (#3885)
jeremylarner Jan 13, 2020
ef5206f
Merge branch 'seekers-of-wisdom' into develop
marcsoiferman-cm Jan 19, 2020
01715c8
Updated Maeko test (#3888)
marcsoiferman-cm Jan 19, 2020
11fe0b3
Fatephase test improvements (#3889)
marcsoiferman-cm Jan 19, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions client/BannedList.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
const bannedList = {
version: '12',
cards: [
'guest-of-honor',
'charge',
'isawa-tadaka',
'karada-district',
'master-of-gisei-toshi',
'kanjo-district',
'jurojin-s-curse',
'hidden-moon-dojo',
'mirumoto-daisho'
]
};

class BannedList {
validate(cards) {
let cardsOnBannedList = cards.filter(card => bannedList.cards.includes(card.id));

let errors = [];

if(cardsOnBannedList.length > 1) {
errors.push(`Contains a card on the FAQ v${bannedList.version} banned list: ${cardsOnBannedList.map(card => card.name).join(', ')}`);
}

return {
version: bannedList.version,
valid: errors.length === 0,
errors: errors,
restrictedCards: cardsOnBannedList
};
}
}

module.exports = BannedList;
4 changes: 2 additions & 2 deletions client/GameComponents/DynastyRow.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ class DynastyRow extends React.Component {
<CardPile
className='removed-from-game-pile discard'
title='Removed From Game'
source='removed from game pile'
source='removed from game'
cards={ this.props.removedFromGame }
onMouseOver={ this.props.onMouseOver }
onMouseOut={ this.props.onMouseOut }
Expand All @@ -318,7 +318,7 @@ class DynastyRow extends React.Component {
<CardPile
className='removed-from-game-pile discard'
title='Removed From Game'
source='removed from game pile'
source='removed from game'
cards={ this.props.removedFromGame }
onMouseOver={ this.props.onMouseOver }
onMouseOut={ this.props.onMouseOut }
Expand Down
3 changes: 1 addition & 2 deletions client/GameComponents/GameConfiguration.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@ class GameConfiguration extends React.Component {
{ name: 'draw', label: 'Draw phase', style: 'col-sm-4' },
{ name: 'preConflict', label: 'Conflict phase', style: 'col-sm-4' },
{ name: 'conflict', label: 'During conflict', style: 'col-sm-4' },
{ name: 'fate', label: 'Fate phase', style: 'col-sm-4' },
{ name: 'regroup', label: 'Regroup phase', style: 'col-sm-4' }
{ name: 'fate', label: 'Fate phase', style: 'col-sm-4' }
];

this.state = {
Expand Down
2 changes: 1 addition & 1 deletion client/GameComponents/StrongholdRow.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class StrongholdRow extends React.Component {
player &&
<img
className={ `card-image imperial-favor ${ this.props.cardSize } ${player.imperialFavor ? '' : 'hidden'} ` }
src={ '/img/' + (player.imperialFavor ? player.imperialFavor : 'political') + '-favor.png' }
src={ '/img/' + (player.imperialFavor ? player.imperialFavor : 'political') + '-favor.jpg' }
/>
}
</div>
Expand Down
2 changes: 2 additions & 0 deletions client/HowToPlay.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ class HowToPlay extends React.Component {
<li>/move-to-conflict - Moves one or more characters into a conflict.</li>
<li>/send-home - Sends a character home from a conflict.</li>
<li>/claim-favor x - Claims the Imperial favor. x should be 'military' or 'political'.</li>
<li>/discard-favor - Discards your Imperial favor.</li>
<li>/move-to-bottom-deck - Will prompt you to select a card to move it to the bottom of it's relevant deck.</li>
<li>/add-fate x - Add 'x' fate to a card.</li>
<li>/rem-fate x - Remove 'x' fate from a card.</li>
<li>/add-fate-ring ring x - Add 'x' fate to 'ring'.</li>
Expand Down
3 changes: 1 addition & 2 deletions client/Profile.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,7 @@ class InnerProfile extends React.Component {
{ name: 'draw', label: 'Draw phase', style: 'col-sm-4' },
{ name: 'preConflict', label: 'Conflict phase', style: 'col-sm-4' },
{ name: 'conflict', label: 'During conflict', style: 'col-sm-4' },
{ name: 'fate', label: 'Fate phase', style: 'col-sm-4' },
{ name: 'regroup', label: 'Regroup phase', style: 'col-sm-4' }
{ name: 'fate', label: 'Fate phase', style: 'col-sm-4' }
];
}

Expand Down
19 changes: 8 additions & 11 deletions client/RestrictedList.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,23 @@
const restrictedList = {
version: '9',
cards: [
'guest-of-honor',
'young-rumormonger',
'kuroi-mori',
'secret-cache',
'rebuild',
'steward-of-law',
'mirumoto-s-fury',
'for-greater-glory',
'forged-edict',
'spyglass',
'charge',
'embrace-the-void',
'pathfinder-s-blade',
'policy-debate',
'a-fate-worse-than-death',
'isawa-tadaka',
'secluded-shrine',
'void-fist',
'the-imperial-palace',
'consumed-by-five-fires',
'cunning-magistrate',
'daidoji-uji',
'miya-satoshi',
'a-fate-worse-than-death',
'void-fist',
'mark-of-shame',
'magistrate-station',
'kakita-toshimoko',
'gateway-to-meido'
]
};
Expand Down
19 changes: 5 additions & 14 deletions client/deck-validator.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ const _ = require('underscore');
const moment = require('moment');

const RestrictedList = require('./RestrictedList');
const BannedList = require('./BannedList');

const openRoles = [
'keeper-of-air',
Expand Down Expand Up @@ -112,6 +113,7 @@ const roleRules = {
class DeckValidator {
constructor(packs) {
this.packs = packs;
this.bannedList = new BannedList();
this.restrictedList = new RestrictedList();
}

Expand Down Expand Up @@ -196,17 +198,6 @@ class DeckValidator {
}
});

let totalConflictChars = _.reduce(deck.conflictCards, (total, card) => {
if(card.card.type === 'character') {
return total + card.count;
}
return total;
}, 0);

if(totalConflictChars > rules.maxConflictCharacters) {
errors.push('Too many conflict characters');
}

let totalInfluence = _.reduce(cardCountByName, (total, card) => {
if(card.influence && card.faction !== deck.faction.value) {
return total + card.influence * card.count;
Expand All @@ -219,17 +210,18 @@ class DeckValidator {
}

let restrictedResult = this.restrictedList.validate(allCards.map(cardQuantity => cardQuantity.card));
let bannedResult = this.bannedList.validate(allCards.map(cardQuantity => cardQuantity.card));

return {
basicRules: errors.length === 0,
noUnreleasedCards: unreleasedCards.length === 0,
officialRole: !role || openRoles.includes(role.id),
faqRestrictedList: restrictedResult.valid,
faqRestrictedList: restrictedResult.valid && bannedResult.valid,
faqVersion: restrictedResult.version,
provinceCount: provinceCount,
dynastyCount: dynastyCount,
conflictCount: conflictCount,
extendedStatus: errors.concat(unreleasedCards).concat(restrictedResult.errors)
extendedStatus: errors.concat(unreleasedCards, restrictedResult.errors, bannedResult.errors)
};
}

Expand All @@ -240,7 +232,6 @@ class DeckValidator {
minimumConflict: 40,
maximumConflict: 45,
requiredProvinces: 5,
maxConflictCharacters: 10,
maxProvince: {
air: 1,
earth: 1,
Expand Down
2 changes: 1 addition & 1 deletion docs/implementing-cards.md
Original file line number Diff line number Diff line change
Expand Up @@ -537,7 +537,7 @@ this.action({

#### Limiting an action to a specific phase

Some actions are limited to a specific phase by their card text. You can pass an optional `phase` property to the action to limit it to just that phase. Valid phases include `'dynasty'`, `'draw'`, `'conflict'`, `'fate'`, `'regroup'`. The default is `'any'` which allows the action to be triggered in any phase.
Some actions are limited to a specific phase by their card text. You can pass an optional `phase` property to the action to limit it to just that phase. Valid phases include `'dynasty'`, `'draw'`, `'conflict'`, `'fate'`. The default is `'any'` which allows the action to be triggered in any phase.

```javascript
this.action({
Expand Down
Binary file added public/img/military-favor.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed public/img/military-favor.png
Binary file not shown.
Binary file added public/img/political-favor.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed public/img/political-favor.png
Binary file not shown.
50 changes: 35 additions & 15 deletions server/game/CardAbility.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,15 @@ const AbilityLimit = require('./abilitylimit.js');
const AbilityDsl = require('./abilitydsl');
const ThenAbility = require('./ThenAbility');
const Costs = require('./costs.js');
const { Locations, CardTypes, EffectNames, Players, TargetModes } = require('./Constants');
const { Locations, CardTypes, EffectNames, Players } = require('./Constants');

class CardAbility extends ThenAbility {
constructor(game, card, properties) {
if(properties.initiateDuel) {
properties.targets = {
challenger: {
cardType: CardTypes.Character,
mode: card.type === CardTypes.Character ? TargetModes.AutoSingle : TargetModes.Single,
controller: Players.Self,
cardCondition: (card, context) => card.isParticipating()
&& (context.source.type === CardTypes.Character ? card === context.source : true)
},
duelTarget: {
dependsOn: 'challenger',
if(card.type === CardTypes.Character) {
let prevCondition = properties.condition;
properties.condition = context => context.source.isParticipating() && (!prevCondition || prevCondition(context));
properties.target = {
cardType: CardTypes.Character,
player: context => {
if(typeof properties.initiateDuel === 'function') {
Expand All @@ -28,12 +22,38 @@ class CardAbility extends ThenAbility {
cardCondition: card => card.isParticipating(),
gameAction: AbilityDsl.actions.duel(context => {
if(typeof properties.initiateDuel === 'function') {
return Object.assign({ challenger: context.targets.challenger }, properties.initiateDuel(context));
return Object.assign({ challenger: context.source }, properties.initiateDuel(context));
}
return Object.assign({ challenger: context.targets.challenger }, properties.initiateDuel);
return Object.assign({ challenger: context.source }, properties.initiateDuel);
})
}
};
};
} else {
properties.targets = {
challenger: {
cardType: CardTypes.Character,
controller: Players.Self,
cardCondition: card => card.isParticipating()
},
duelTarget: {
dependsOn: 'challenger',
cardType: CardTypes.Character,
player: context => {
if(typeof properties.initiateDuel === 'function') {
return properties.initiateDuel(context).opponentChoosesDuelTarget ? Players.Opponent : Players.Self;
}
return properties.initiateDuel.opponentChoosesDuelTarget ? Players.Opponent : Players.Self;
},
controller: Players.Opponent,
cardCondition: card => card.isParticipating(),
gameAction: AbilityDsl.actions.duel(context => {
if(typeof properties.initiateDuel === 'function') {
return Object.assign({ challenger: context.targets.challenger }, properties.initiateDuel(context));
}
return Object.assign({ challenger: context.targets.challenger }, properties.initiateDuel);
})
}
};
}
}
super(game, card, properties);

Expand Down
1 change: 1 addition & 0 deletions server/game/Constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ export enum EffectNames {
RestrictNumberOfDefenders = 'restrictNumberOfDefenders',
ResolveConflictEarly = 'resolveConflictEarly',
SetBaseGlory = "setBaseGlory",
EventsCannotBeCancelled = 'eventsCannotBeCancelled',
ForceConflictUnopposed = 'forceConflictUnopposed'
};

Expand Down
3 changes: 2 additions & 1 deletion server/game/Effects/GainAbility.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ class GainAbility extends EffectValue {
constructor(abilityType, ability) {
super();
this.abilityType = abilityType;
this.properties = ability;
this.grantedAbilityLimits = {};
if(ability.properties) {
let newProps = { printedAbility: false, abilityIdentifier: ability.abilityIdentifier, origin: ability.card };
Expand All @@ -19,6 +18,8 @@ class GainAbility extends EffectValue {
newProps.max = AbilityLimit.repeatable(ability.properties.max.max, ability.properties.max.eventName);
}
this.properties = Object.assign({}, ability.properties, newProps);
} else {
this.properties = Object.assign({ printedAbility: false }, ability);
}
if(abilityType === AbilityTypes.Persistent && !this.properties.location) {
this.properties.location = Locations.PlayArea;
Expand Down
2 changes: 2 additions & 0 deletions server/game/Effects/restriction.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ const checkRestrictions = {
context.player && context.player === effect.context.player.opponent && context.source.type === 'ring',
opponentsTriggeredAbilities: (context, effect) =>
context.player === effect.context.player.opponent && context.ability.isTriggeredAbility(),
opponentsCardAbilities: (context, effect) =>
context.player === effect.context.player.opponent && context.ability.isCardAbility(),
reactions: context => context.ability.abilityType === AbilityTypes.Reaction,
source: (context, effect) => context.source === effect.context.source,
keywordAbilities: context => context.ability.isKeywordAbility(),
Expand Down
2 changes: 1 addition & 1 deletion server/game/Events/InitiateAbilityEventWindow.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class InitiateAbilityInterruptWindow extends TriggeredAbilityWindow {
getMinCostReduction() {
if(this.playEvent) {
const context = this.playEvent.context;
const alternatePools = context.player.getAlternateFatePools(this.playEvent.playType, context.source);
const alternatePools = context.player.getAlternateFatePools(this.playEvent.playType, context.source, context);
const alternatePoolTotal = alternatePools.reduce((total, pool) => total + pool.fate, 0);
const maxPlayerFate = context.player.checkRestrictions('spendFate', context) ? context.player.fate : 0;
return Math.max(context.ability.getReducedCost(context) - maxPlayerFate - alternatePoolTotal, 0);
Expand Down
8 changes: 7 additions & 1 deletion server/game/GameActions/CancelAction.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { GameAction, GameActionProperties } from './GameAction';
import TriggeredAbilityContext = require('../TriggeredAbilityContext');
import { CardTypes } from '../Constants'

export interface CancelActionProperties extends GameActionProperties {
replacementGameAction?: GameAction;
Expand Down Expand Up @@ -27,7 +28,12 @@ export class CancelAction extends GameAction {
return false;
}
let { replacementGameAction } = this.getProperties(context);
return !context.event.cannotBeCancelled &&
let cannotBeCancelled = context.event.cannotBeCancelled;
if (context.event.card && context.event.card.getType() === CardTypes.Event && context.event.card.owner && context.event.card.owner.eventsCannotBeCancelled()) {
cannotBeCancelled = true;
}

return !cannotBeCancelled &&
(!replacementGameAction || replacementGameAction.hasLegalTarget(context, additionalProperties));
}

Expand Down
2 changes: 1 addition & 1 deletion server/game/GameActions/ChosenDiscardAction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ export class ChosenDiscardAction extends PlayerAction {
context: context,
mode: TargetModes.Exactly,
numCards: amount,
ordered: true,
location: Locations.Hand,
controller: player === context.player ? Players.Self : Players.Opponent,
onSelect: (player, cards) => {
Expand All @@ -68,6 +67,7 @@ export class ChosenDiscardAction extends PlayerAction {

eventHandler(event): void {
event.context.game.addMessage('{0} discards {1}', event.player, event.cards);
event.discardedCards = event.cards;
for(let card of event.cards) {
event.player.moveCard(card, card.isDynasty ? Locations.DynastyDiscardPile : Locations.ConflictDiscardPile);
}
Expand Down
5 changes: 3 additions & 2 deletions server/game/GameActions/GameActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ import { RefillFaceupAction, RefillFaceupProperties } from './RefillFaceupAction
import { RemoveFateAction, RemoveFateProperties } from './RemoveFateAction';
import { RemoveFromGameAction, RemoveFromGameProperties } from './RemoveFromGameAction';
import { ResolveAbilityAction, ResolveAbilityProperties } from './ResolveAbilityAction';
import { ResolveConflictRingAction, ResolveConflictRingProperties } from './ResolveConflictRingAction';
import { ResolveConflictRingAction } from './ResolveConflictRingAction';
import { ResolveElementAction, ResolveElementProperties } from './ResolveElementAction';
import { ReturnRingAction, ReturnRingProperties } from './ReturnRingAction';
import { ReturnToDeckAction, ReturnToDeckProperties } from './ReturnToDeckAction';
Expand All @@ -73,6 +73,7 @@ import { TransferHonorAction, TransferHonorProperties } from './TransferHonorAct
import { TurnCardFacedownAction, TurnCardFacedownProperties } from './TurnCardFacedownAction';
import { GloryCountAction, GloryCountProperties } from './GloryCountAction';
import { ClaimFavorAction, ClaimFavorProperties } from './ClaimFavorAction';
import { RingActionProperties } from './RingAction';

const GameActions = {
// card
Expand Down Expand Up @@ -130,7 +131,7 @@ const GameActions = {
takeHonor: (propertyFactory: TransferHonorProperties | ((context: TriggeredAbilityContext) => TransferHonorProperties) = {}) => new TransferHonorAction(propertyFactory), // amount = 1
// ring actions
placeFateOnRing: (propertyFactory: PlaceFateRingProperties | ((context: TriggeredAbilityContext) => PlaceFateRingProperties) = {}) => new PlaceFateRingAction(propertyFactory), // amount = 1, origin
resolveConflictRing: (propertyFactory: ResolveConflictRingProperties | ((context: TriggeredAbilityContext) => ResolveConflictRingProperties) = {}) => new ResolveConflictRingAction(propertyFactory), // resolveAsAttacker = true
resolveConflictRing: (propertyFactory: RingActionProperties | ((context: TriggeredAbilityContext) => RingActionProperties) = {}) => new ResolveConflictRingAction(propertyFactory), // resolveAsAttacker = true
resolveRingEffect: (propertyFactory: ResolveElementProperties | ((context: TriggeredAbilityContext) => ResolveElementProperties) = {}) => new ResolveElementAction(propertyFactory), // options = false
returnRing: (propertyFactory: ReturnRingProperties | ((context: TriggeredAbilityContext) => ReturnRingProperties) = {}) => new ReturnRingAction(propertyFactory),
ringLastingEffect: (propertyFactory: LastingEffectRingProperties | ((context: TriggeredAbilityContext) => LastingEffectRingProperties)) => new LastingEffectRingAction(propertyFactory), // duration = 'untilEndOfConflict', effect, condition, until
Expand Down
Loading