mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-20 12:48: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.ExploreAi;
|
||||||
import forge.ai.ability.LearnAi;
|
import forge.ai.ability.LearnAi;
|
||||||
import forge.ai.simulation.SpellAbilityPicker;
|
import forge.ai.simulation.SpellAbilityPicker;
|
||||||
|
import forge.card.CardStateName;
|
||||||
import forge.card.MagicColor;
|
import forge.card.MagicColor;
|
||||||
import forge.card.mana.ManaCost;
|
import forge.card.mana.ManaCost;
|
||||||
import forge.deck.CardPool;
|
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);
|
final CardCollectionView hand = player.getCardsIn(ZoneType.Hand);
|
||||||
CardCollection lands = new CardCollection(battlefield);
|
CardCollection lands = new CardCollection(battlefield);
|
||||||
lands.addAll(hand);
|
lands.addAll(hand);
|
||||||
lands = CardLists.filter(lands, CardPredicates.Presets.LANDS);
|
lands = CardLists.filter(lands, CardPredicates.Presets.LANDS);
|
||||||
int maxCmcInHand = Aggregates.max(hand, CardPredicates.Accessors.fnGetCmc);
|
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) {
|
for (final SpellAbility sa : spellAbilities) {
|
||||||
if (sa.isCycling()) {
|
if (sa.isCycling()) {
|
||||||
if (lands.size() >= Math.max(maxCmcInHand, 6)) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1454,6 +1460,13 @@ public class AiController {
|
|||||||
if (!game.getPhaseHandler().is(PhaseType.MAIN1) || !isSafeToHoldLandDropForMain2(land)) {
|
if (!game.getPhaseHandler().is(PhaseType.MAIN1) || !isSafeToHoldLandDropForMain2(land)) {
|
||||||
final List<SpellAbility> abilities = Lists.newArrayList();
|
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);
|
LandAbility la = new LandAbility(land, player, null);
|
||||||
la.setCardState(land.getCurrentState());
|
la.setCardState(land.getCurrentState());
|
||||||
if (la.canPlay()) {
|
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 isShrine() { return getType().hasSubtype("Shrine"); }
|
||||||
|
|
||||||
public final boolean isAttachment() { return isAura() || isEquipment() || isFortification(); }
|
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 isScheme() { return getType().isScheme(); }
|
||||||
public final boolean isPhenomenon() { return getType().isPhenomenon(); }
|
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.Function;
|
||||||
import com.google.common.base.Predicate;
|
import com.google.common.base.Predicate;
|
||||||
|
|
||||||
|
import forge.card.CardStateName;
|
||||||
import forge.game.CardTraitBase;
|
import forge.game.CardTraitBase;
|
||||||
import forge.game.combat.CombatUtil;
|
import forge.game.combat.CombatUtil;
|
||||||
import forge.game.keyword.Keyword;
|
import forge.game.keyword.Keyword;
|
||||||
@@ -653,7 +654,7 @@ public final class CardPredicates {
|
|||||||
public static final Predicate<Card> LANDS = new Predicate<Card>() {
|
public static final Predicate<Card> LANDS = new Predicate<Card>() {
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Card c) {
|
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