diff --git a/forge-ai/src/main/java/forge/ai/ComputerUtilCost.java b/forge-ai/src/main/java/forge/ai/ComputerUtilCost.java index 89214f21fe6..d67690e8371 100644 --- a/forge-ai/src/main/java/forge/ai/ComputerUtilCost.java +++ b/forge-ai/src/main/java/forge/ai/ComputerUtilCost.java @@ -1,47 +1,22 @@ package forge.ai; -import java.util.List; -import java.util.Set; - -import forge.game.ability.ApiType; -import org.apache.commons.lang3.ObjectUtils; -import org.apache.commons.lang3.StringUtils; - import com.google.common.base.Predicate; import com.google.common.base.Predicates; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import com.google.common.collect.Sets; - import forge.ai.AiCardMemory.MemorySet; import forge.ai.ability.AnimateAi; import forge.card.ColorSet; import forge.game.Game; import forge.game.ability.AbilityUtils; -import forge.game.card.Card; -import forge.game.card.CardCollection; -import forge.game.card.CardCollectionView; -import forge.game.card.CardFactoryUtil; -import forge.game.card.CardLists; -import forge.game.card.CardPredicates; +import forge.game.ability.ApiType; +import forge.game.card.*; import forge.game.card.CardPredicates.Presets; -import forge.game.card.CardUtil; -import forge.game.card.CounterEnumType; -import forge.game.card.CounterType; import forge.game.combat.Combat; -import forge.game.cost.Cost; -import forge.game.cost.CostDamage; -import forge.game.cost.CostDiscard; -import forge.game.cost.CostPart; -import forge.game.cost.CostPayLife; -import forge.game.cost.CostPayment; -import forge.game.cost.CostPutCounter; -import forge.game.cost.CostRemoveAnyCounter; -import forge.game.cost.CostRemoveCounter; -import forge.game.cost.CostSacrifice; -import forge.game.cost.CostTapType; -import forge.game.cost.PaymentDecision; +import forge.game.cost.*; import forge.game.keyword.Keyword; +import forge.game.phase.PhaseType; import forge.game.player.Player; import forge.game.spellability.Spell; import forge.game.spellability.SpellAbility; @@ -49,6 +24,11 @@ import forge.game.zone.ZoneType; import forge.util.MyRandom; import forge.util.TextUtil; import forge.util.collect.FCollectionView; +import org.apache.commons.lang3.ObjectUtils; +import org.apache.commons.lang3.StringUtils; + +import java.util.List; +import java.util.Set; public class ComputerUtilCost { @@ -154,8 +134,14 @@ public class ComputerUtilCost { final CostDiscard disc = (CostDiscard) part; final String type = disc.getType(); - if (type.equals("CARDNAME") && source.getAbilityText().contains("Bloodrush")) { - continue; + if (type.equals("CARDNAME")) { + if (source.getAbilityText().contains("Bloodrush")) { + continue; + } else if (ai.getGame().getPhaseHandler().is(PhaseType.END_OF_TURN, ai) + && ai.getCardsIn(ZoneType.Hand).size() > ai.getMaxHandSize()) { + // Better do something than just discard stuff + return true; + } } final CardCollection typeList = CardLists.getValidCards(hand, type.split(","), source.getController(), source, sa); if (typeList.size() > ai.getMaxHandSize()) { diff --git a/forge-ai/src/main/java/forge/ai/SpellAbilityAi.java b/forge-ai/src/main/java/forge/ai/SpellAbilityAi.java index adcfe9728cd..07ff3f7179b 100644 --- a/forge-ai/src/main/java/forge/ai/SpellAbilityAi.java +++ b/forge-ai/src/main/java/forge/ai/SpellAbilityAi.java @@ -1,12 +1,7 @@ package forge.ai; -import java.util.Collection; -import java.util.List; -import java.util.Map; - import com.google.common.collect.Iterables; import com.google.common.collect.Lists; - import forge.card.CardStateName; import forge.card.ICardFace; import forge.card.mana.ManaCost; @@ -24,8 +19,13 @@ import forge.game.player.PlayerController.BinaryChoiceType; import forge.game.spellability.AbilitySub; import forge.game.spellability.SpellAbility; import forge.game.spellability.SpellAbilityCondition; +import forge.game.zone.ZoneType; import forge.util.MyRandom; +import java.util.Collection; +import java.util.List; +import java.util.Map; + /** * Base class for API-specific AI logic *

@@ -72,10 +72,12 @@ public abstract class SpellAbilityAi { if (sa.hasParam("AILogic")) { final String logic = sa.getParam("AILogic"); + final boolean alwaysOnDiscard = "AlwaysOnDiscard".equals(logic) && ai.getGame().getPhaseHandler().is(PhaseType.END_OF_TURN, ai) + && ai.getCardsIn(ZoneType.Hand).size() > ai.getMaxHandSize(); if (!checkAiLogic(ai, sa, logic)) { return false; } - if (!checkPhaseRestrictions(ai, sa, ai.getGame().getPhaseHandler(), logic)) { + if (!alwaysOnDiscard && !checkPhaseRestrictions(ai, sa, ai.getGame().getPhaseHandler(), logic)) { return false; } } else { diff --git a/forge-gui/res/cardsfolder/m/magma_opus.txt b/forge-gui/res/cardsfolder/m/magma_opus.txt index d93b45ca90f..0a629db0e3a 100644 --- a/forge-gui/res/cardsfolder/m/magma_opus.txt +++ b/forge-gui/res/cardsfolder/m/magma_opus.txt @@ -5,6 +5,6 @@ A:SP$ DealDamage | Cost$ 6 U R | ValidTgts$ Creature,Player,Planeswalker | TgtPr SVar:DBTap:DB$ Tap | TargetMin$ 2 | TargetMax$ 2 | ValidTgts$ Permanent | TgtPrompt$ Select target permanent to tap | SubAbility$ DBToken SVar:DBToken:DB$ Token | TokenScript$ ur_4_4_elemental | SubAbility$ DBDraw SVar:DBDraw:DB$ Draw | NumCards$ 2 -A:AB$ Token | Cost$ UR UR Discard<1/CARDNAME> | ActivationZone$ Hand | TokenScript$ c_a_treasure_sac | SpellDescription$ Create a Treasure token. +A:AB$ Token | Cost$ UR UR Discard<1/CARDNAME> | ActivationZone$ Hand | TokenScript$ c_a_treasure_sac | AILogic$ AlwaysOnDiscard | SpellDescription$ Create a Treasure token. DeckHas:Ability$Token Oracle:Magma Opus deals 4 damage divided as you choose among any number of targets. Tap two target permanents. Create a 4/4 blue and red Elemental creature token. Draw two cards.\n{U/R}{U/R}, Discard Magma Opus: Create a Treasure token.