mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-20 04:38:00 +00:00
Merge branch 'AImdfc' into 'master'
AI: basic support playing MDFC lands See merge request core-developers/forge!4589
This commit is contained in:
@@ -34,6 +34,7 @@ import forge.ai.ability.ChangeZoneAi;
|
||||
import forge.ai.ability.ExploreAi;
|
||||
import forge.ai.ability.LearnAi;
|
||||
import forge.ai.simulation.SpellAbilityPicker;
|
||||
import forge.card.CardStateName;
|
||||
import forge.card.MagicColor;
|
||||
import forge.card.mana.ManaCost;
|
||||
import forge.deck.CardPool;
|
||||
@@ -432,17 +433,22 @@ public class AiController {
|
||||
}
|
||||
}
|
||||
|
||||
// don't play the land if it has cycling and enough lands are available
|
||||
final FCollectionView<SpellAbility> spellAbilities = c.getSpellAbilities();
|
||||
|
||||
final CardCollectionView hand = player.getCardsIn(ZoneType.Hand);
|
||||
CardCollection lands = new CardCollection(battlefield);
|
||||
lands.addAll(hand);
|
||||
lands = CardLists.filter(lands, CardPredicates.Presets.LANDS);
|
||||
int maxCmcInHand = Aggregates.max(hand, CardPredicates.Accessors.fnGetCmc);
|
||||
|
||||
if (lands.size() >= Math.max(maxCmcInHand, 6)) {
|
||||
// don't play MDFC land if other side is spell and enough lands are available
|
||||
if (!c.isLand() || (c.isModal() && !c.getState(CardStateName.Modal).getType().isLand())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// don't play the land if it has cycling and enough lands are available
|
||||
final FCollectionView<SpellAbility> spellAbilities = c.getSpellAbilities();
|
||||
for (final SpellAbility sa : spellAbilities) {
|
||||
if (sa.isCycling()) {
|
||||
if (lands.size() >= Math.max(maxCmcInHand, 6)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1454,6 +1460,13 @@ public class AiController {
|
||||
if (!game.getPhaseHandler().is(PhaseType.MAIN1) || !isSafeToHoldLandDropForMain2(land)) {
|
||||
final List<SpellAbility> abilities = Lists.newArrayList();
|
||||
|
||||
// TODO extend this logic to evaluate MDFC with both sides land
|
||||
// this can only happen if its a MDFC land
|
||||
if (!land.isLand()) {
|
||||
land.setState(CardStateName.Modal, true);
|
||||
land.setBackSide(true);
|
||||
}
|
||||
|
||||
LandAbility la = new LandAbility(land, player, null);
|
||||
la.setCardState(land.getCurrentState());
|
||||
if (la.canPlay()) {
|
||||
|
||||
@@ -4529,7 +4529,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
||||
public final boolean isShrine() { return getType().hasSubtype("Shrine"); }
|
||||
|
||||
public final boolean isAttachment() { return isAura() || isEquipment() || isFortification(); }
|
||||
public final boolean isHistoric() {return getType().isLegendary() || isArtifact() || getType().hasSubtype("Saga");}
|
||||
public final boolean isHistoric() { return getType().isLegendary() || isArtifact() || getType().hasSubtype("Saga"); }
|
||||
|
||||
public final boolean isScheme() { return getType().isScheme(); }
|
||||
public final boolean isPhenomenon() { return getType().isPhenomenon(); }
|
||||
|
||||
@@ -22,6 +22,7 @@ import java.util.Comparator;
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Predicate;
|
||||
|
||||
import forge.card.CardStateName;
|
||||
import forge.game.CardTraitBase;
|
||||
import forge.game.combat.CombatUtil;
|
||||
import forge.game.keyword.Keyword;
|
||||
@@ -653,7 +654,7 @@ public final class CardPredicates {
|
||||
public static final Predicate<Card> LANDS = new Predicate<Card>() {
|
||||
@Override
|
||||
public boolean apply(Card c) {
|
||||
return c.isLand();
|
||||
return c.isLand() || (!c.isInZone(ZoneType.Battlefield) && c.isModal() && c.getState(CardStateName.Modal).getType().isLand());
|
||||
}
|
||||
};
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user