Partner commanders: Partner, Partner—<variant>, Partner with, Background, Doctor
A Commander/Brawl deck can now have two commanders when their abilities allow it. Partner abilities are parsed from oracle text (Scryfall's keyword list files every "Partner—Survivors"-style variant under plain "Partner"), and a second search box offers only cards that can pair with the commander. The legality check accepts a valid pair and checks color identity against both; suggestions and decklist import/export handle both commanders. Closes #4
This commit is contained in:
@@ -214,18 +214,26 @@ impl Catalog {
|
||||
return Ok(vec![]);
|
||||
}
|
||||
|
||||
let commander_oid = deck.commander_oracle_id.clone();
|
||||
// The commanders: both halves of a partner pair, or just the one.
|
||||
let mut commander_oids: Vec<String> = contents
|
||||
.iter()
|
||||
.filter(|e| e.is_commander)
|
||||
.map(|e| e.card.oracle_id.clone())
|
||||
.collect();
|
||||
if commander_oids.is_empty() {
|
||||
commander_oids.extend(deck.commander_oracle_id.clone());
|
||||
}
|
||||
|
||||
// Color identity for the hard filter: the commander's, or (no
|
||||
// Color identity for the hard filter: the commanders' combined, or (no
|
||||
// commander) the union of every deck card's identity — otherwise a
|
||||
// mono-color deck would be offered all five colors.
|
||||
let identity_mask: u8 = match &commander_oid {
|
||||
Some(cmd) => contents
|
||||
let identity_mask: u8 = if commander_oids.is_empty() {
|
||||
contents.iter().fold(0u8, |m, e| m | e.card.color_identity.0)
|
||||
} else {
|
||||
contents
|
||||
.iter()
|
||||
.find(|e| &e.card.oracle_id == cmd)
|
||||
.map(|e| e.card.color_identity.0)
|
||||
.unwrap_or(0),
|
||||
None => contents.iter().fold(0u8, |m, e| m | e.card.color_identity.0),
|
||||
.filter(|e| commander_oids.contains(&e.card.oracle_id))
|
||||
.fold(0u8, |m, e| m | e.card.color_identity.0)
|
||||
};
|
||||
|
||||
// --- Tribal targets: dominant creature subtypes ---
|
||||
@@ -240,10 +248,10 @@ impl Catalog {
|
||||
"subtype",
|
||||
/* creatures_only = */ true,
|
||||
)?;
|
||||
let commander_subtypes = match &commander_oid {
|
||||
Some(cmd) => self.creature_subtypes_of(cmd)?,
|
||||
None => HashSet::new(),
|
||||
};
|
||||
let mut commander_subtypes = HashSet::new();
|
||||
for cmd in &commander_oids {
|
||||
commander_subtypes.extend(self.creature_subtypes_of(cmd)?);
|
||||
}
|
||||
let mut tribal_targets: HashSet<String> = tribal_counts
|
||||
.iter()
|
||||
.filter(|(_, &n)| n >= tribal_threshold)
|
||||
@@ -253,10 +261,10 @@ impl Catalog {
|
||||
|
||||
// --- Mechanic targets: non-evergreen keywords ---
|
||||
let keyword_counts = self.deck_attr_counts(deck_id, "card_keywords", "keyword", false)?;
|
||||
let commander_keywords = match &commander_oid {
|
||||
Some(cmd) => self.keywords_of(cmd)?,
|
||||
None => HashSet::new(),
|
||||
};
|
||||
let mut commander_keywords = HashSet::new();
|
||||
for cmd in &commander_oids {
|
||||
commander_keywords.extend(self.keywords_of(cmd)?);
|
||||
}
|
||||
let mut mechanic_targets: HashSet<String> = keyword_counts
|
||||
.iter()
|
||||
.filter(|(k, &n)| n >= 3 && !is_evergreen(k))
|
||||
@@ -810,6 +818,27 @@ mod tests {
|
||||
assert!(!out.iter().any(|s| s.card.oracle_id == "black-elf"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn partner_commanders_combine_their_identities() {
|
||||
let fx = test_support::make();
|
||||
let cat = &fx.catalog;
|
||||
// Green Elf and white Angel as partner commanders: G+W is allowed.
|
||||
let d = cat.create_deck("Partners", None).unwrap();
|
||||
cat.set_deck_card(d.id, "llanowar-elves", 1, false, false).unwrap();
|
||||
cat.set_deck_card(d.id, "serra-angel", 1, false, false).unwrap();
|
||||
cat.set_deck_commanders(d.id, &["llanowar-elves", "serra-angel"]).unwrap();
|
||||
|
||||
add_ref_card(cat, "white-elf", "White Elf", "Creature — Elf", "W", "", &["Elf"], &[], 0, None);
|
||||
add_ref_card(cat, "black-elf", "Black Elf", "Creature — Elf", "B", "", &["Elf"], &[], 0, None);
|
||||
|
||||
let out = cat.suggest_cards(d.id, 50, 0, SuggestOptions::default()).unwrap();
|
||||
assert!(
|
||||
out.iter().any(|s| s.card.oracle_id == "white-elf"),
|
||||
"the partner's white widens the identity, and the Elf type still counts"
|
||||
);
|
||||
assert!(!out.iter().any(|s| s.card.oracle_id == "black-elf"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mana_base_fit_flags_a_missing_color() {
|
||||
let fx = test_support::make();
|
||||
|
||||
Reference in New Issue
Block a user