Compare commits

...

6 Commits

Author SHA1 Message Date
Hans Mackowiak
c32b84b40c Update EffectAi.java 2025-07-30 11:19:02 +02:00
Hans Mackowiak
6962c2cf99 EffectAi: first try of generic cantAttack and cantBlock 2025-07-30 11:14:11 +02:00
Hans Mackowiak
b7ec60863a ~ start of DetainAi 2025-07-30 11:14:11 +02:00
Hans Mackowiak
239cf3ece7 more hidden keywords to effects 2025-07-30 11:14:11 +02:00
Hans Mackowiak
06781fb6ff moved another part to EffectEffect 2025-07-30 11:14:11 +02:00
Hans Mackowiak
a85f00043b Add DetainEffect 2025-07-30 11:14:11 +02:00
28 changed files with 320 additions and 63 deletions

View File

@@ -2737,7 +2737,7 @@ public class ComputerUtil {
return safeCards;
}
public static Card getKilledByTargeting(final SpellAbility sa, CardCollectionView validCards) {
public static Card getKilledByTargeting(final SpellAbility sa, Iterable<Card> validCards) {
CardCollection killables = CardLists.filter(validCards, c -> c.getController() != sa.getActivatingPlayer() && c.getSVar("Targeting").equals("Dies"));
return ComputerUtilCard.getBestCreatureAI(killables);
}

View File

@@ -77,6 +77,7 @@ public enum SpellApiToAi {
.put(ApiType.DelayedTrigger, DelayedTriggerAi.class)
.put(ApiType.Destroy, DestroyAi.class)
.put(ApiType.DestroyAll, DestroyAllAi.class)
.put(ApiType.Detain, DetainAi.class)
.put(ApiType.Dig, DigAi.class)
.put(ApiType.DigMultiple, DigMultipleAi.class)
.put(ApiType.DigUntil, DigUntilAi.class)

View File

@@ -0,0 +1,119 @@
package forge.ai.ability;
import java.util.List;
import java.util.function.Predicate;
import forge.ai.AiAttackController;
import forge.ai.ComputerUtil;
import forge.ai.ComputerUtilCard;
import forge.ai.SpellAbilityAi;
import forge.game.Game;
import forge.game.card.Card;
import forge.game.card.CardCollection;
import forge.game.card.CardLists;
import forge.game.card.CardPredicates;
import forge.game.combat.CombatUtil;
import forge.game.phase.PhaseHandler;
import forge.game.phase.PhaseType;
import forge.game.player.Player;
import forge.game.spellability.SpellAbility;
import forge.game.zone.ZoneType;
public class DetainAi extends SpellAbilityAi {
Predicate<Card> CREATURE_OR_TAP_ABILITY = c -> {
if (c.isCreature()) {
return true;
}
for (final SpellAbility sa : c.getSpellAbilities()) {
if (sa.isAbility() && sa.getPayCosts().hasTapCost()) {
return true;
}
}
return false;
};
protected boolean prefTargeting(final Player ai, final Card source, final SpellAbility sa, final boolean mandatory) {
final Game game = ai.getGame();
CardCollection list = CardLists.getTargetableCards(ai.getOpponents().getCardsIn(ZoneType.Battlefield), sa);
list = CardLists.filter(list, CREATURE_OR_TAP_ABILITY);
// Filter AI-specific targets if provided
list = ComputerUtil.filterAITgts(sa, ai, list, true);
if (list.isEmpty()) {
return false;
}
while (sa.canAddMoreTarget()) {
Card choice = null;
if (list.isEmpty()) {
if (!sa.isMinTargetChosen() || sa.isZeroTargets()) {
if (!mandatory) {
sa.resetTargets();
}
return false;
}
}
PhaseHandler phase = game.getPhaseHandler();
final Player opp = AiAttackController.choosePreferredDefenderPlayer(ai);
Card primeTarget = ComputerUtil.getKilledByTargeting(sa, list);
if (primeTarget != null) {
choice = primeTarget;
} else if (phase.isPlayerTurn(ai) && phase.getPhase().isBefore(PhaseType.COMBAT_DECLARE_BLOCKERS)) {
// Tap creatures possible blockers before combat during AI's turn.
List<Card> attackers;
if (phase.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS)) {
//Combat has already started
attackers = game.getCombat().getAttackers();
} else {
attackers = CardLists.filter(ai.getCreaturesInPlay(), c -> CombatUtil.canAttack(c, opp));
attackers.remove(source);
}
List<Card> creatureList = CardLists.filter(list, CardPredicates.possibleBlockerForAtLeastOne(attackers));
// TODO check if own creature would be forced to attack and we want to keep it alive
if (!attackers.isEmpty() && !creatureList.isEmpty()) {
choice = ComputerUtilCard.getBestCreatureAI(creatureList);
} else if (sa.isTrigger() || ComputerUtil.castSpellInMain1(ai, sa)) {
choice = ComputerUtilCard.getMostExpensivePermanentAI(list);
}
} else if (phase.isPlayerTurn(opp)
&& phase.getPhase().isBefore(PhaseType.COMBAT_DECLARE_ATTACKERS)) {
// Tap creatures possible blockers before combat during AI's turn.
if (list.anyMatch(CardPredicates.CREATURES)) {
List<Card> creatureList = CardLists.filter(list, c -> c.isCreature() && CombatUtil.canAttack(c, opp));
choice = ComputerUtilCard.getBestCreatureAI(creatureList);
} else { // no creatures available
choice = ComputerUtilCard.getMostExpensivePermanentAI(list);
}
} else {
choice = ComputerUtilCard.getMostExpensivePermanentAI(list);
}
if (choice == null) { // can't find anything left
if (!sa.isMinTargetChosen() || sa.isZeroTargets()) {
if (!mandatory) {
sa.resetTargets();
}
return false;
} else {
if (!ComputerUtil.shouldCastLessThanMax(ai, source)) {
return false;
}
break;
}
}
list.remove(choice);
sa.getTargets().add(choice);
}
return true;
}
}

View File

@@ -23,8 +23,10 @@ import forge.game.replacement.ReplacementType;
import forge.game.spellability.SpellAbility;
import forge.game.spellability.SpellAbilityStackInstance;
import forge.game.spellability.TargetRestrictions;
import forge.game.staticability.StaticAbilityMode;
import forge.game.zone.MagicStack;
import forge.game.zone.ZoneType;
import forge.util.FileSection;
import forge.util.MyRandom;
import forge.util.TextUtil;
import forge.util.collect.FCollectionView;
@@ -37,12 +39,12 @@ public class EffectAi extends SpellAbilityAi {
@Override
protected AiAbilityDecision checkApiLogic(final Player ai, final SpellAbility sa) {
final Game game = ai.getGame();
final PhaseHandler phase = game.getPhaseHandler();
boolean randomReturn = MyRandom.getRandom().nextFloat() <= .6667;
String logic = "";
if (sa.hasParam("AILogic")) {
logic = sa.getParam("AILogic");
final PhaseHandler phase = game.getPhaseHandler();
if (logic.equals("BeginningOfOppTurn")) {
if (!phase.getPlayerTurn().isOpponentOf(ai) || phase.getPhase().isAfter(PhaseType.DRAW)) {
return new AiAbilityDecision(0, AiPlayDecision.CantPlayAi);
@@ -383,6 +385,118 @@ public class EffectAi extends SpellAbilityAi {
return new AiAbilityDecision(0, AiPlayDecision.CantPlayAi);
}
}
} else if (sa.hasParam("RememberObjects")) { //generic
boolean cantAttack = false;
boolean cantBlock = false;
boolean cantActivate = false;
String duraction = sa.getParam("Duration");
String matchStr = "Card.IsRemembered";
for (String st : sa.getParam("StaticAbilities").split(",")) {
Map<String, String> params = FileSection.parseToMap(sa.getSVar(st), FileSection.DOLLAR_SIGN_KV_SEPARATOR);
List<StaticAbilityMode> modes = StaticAbilityMode.listValueOf(params.get("Mode"));
if (modes.contains(StaticAbilityMode.CantAttack) && matchStr.equals(params.get("ValidCard"))) {
cantAttack = true;
}
if (modes.contains(StaticAbilityMode.CantBlock) && matchStr.equals(params.get("ValidCard"))) {
cantBlock = true;
}
if (modes.contains(StaticAbilityMode.CantBlockBy) && matchStr.equals(params.get("ValidBlocker"))) {
cantBlock = true;
}
if (modes.contains(StaticAbilityMode.CantBeActivated) && matchStr.equals(params.get("ValidCard"))) {
cantActivate = true;
}
}
// TODO add more cases later
if (!cantAttack && !cantBlock && !cantActivate) {
return new AiAbilityDecision(0, AiPlayDecision.CantPlayAi);
}
if (cantBlock && duraction == null && phase.isPlayerTurn(ai) && !phase.getPhase().isBefore(PhaseType.COMBAT_DECLARE_BLOCKERS)) {
return new AiAbilityDecision(0, AiPlayDecision.CantPlayAi);
}
if (sa.usesTargeting()) {
final Player opp = AiAttackController.choosePreferredDefenderPlayer(ai);
CardCollection list = new CardCollection(CardUtil.getValidCardsToTarget(sa));
list = ComputerUtil.filterAITgts(sa, ai, list, true);
if (list.isEmpty()) {
return new AiAbilityDecision(0, AiPlayDecision.CantPlayAi);
}
List<Card> oppCreatures = CardLists.filterAsList(list, c -> {
return c.isCreature() && c.getController().isOpponentOf(ai);
});
List<Card> oppWithAbilities = CardLists.filterAsList(list, c -> {
return !c.isCreature() && c.getController().isOpponentOf(ai) && c.getSpellAbilities().anyMatch(SpellAbility::isActivatedAbility);
});
if (cantAttack || cantBlock) {
if (oppCreatures.isEmpty()) {
if (!cantActivate || oppWithAbilities.isEmpty()) {
return new AiAbilityDecision(0, AiPlayDecision.CantPlayAi);
}
}
}
while (sa.canAddMoreTarget()) {
Card choice = null;
if (cantAttack && cantBlock && !oppCreatures.isEmpty()) {
Card primeTarget = ComputerUtil.getKilledByTargeting(sa, oppCreatures);
if (primeTarget != null) {
choice = primeTarget;
} else if (phase.isPlayerTurn(ai) && phase.getPhase().isBefore(PhaseType.COMBAT_DECLARE_BLOCKERS)) {
// Tap creatures possible blockers before combat during AI's turn.
List<Card> attackers;
if (phase.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS)) {
//Combat has already started
attackers = game.getCombat().getAttackers();
} else {
attackers = CardLists.filter(ai.getCreaturesInPlay(), c -> CombatUtil.canAttack(c, opp));
}
List<Card> creatureList = CardLists.filter(list, CardPredicates.possibleBlockerForAtLeastOne(attackers));
// TODO check if own creature would be forced to attack and we want to keep it alive
if (!attackers.isEmpty() && !creatureList.isEmpty()) {
choice = ComputerUtilCard.getBestCreatureAI(creatureList);
} else if (sa.isTrigger() || ComputerUtil.castSpellInMain1(ai, sa)) {
choice = ComputerUtilCard.getMostExpensivePermanentAI(list);
}
}
} // TODO add logic to tap non creatures with activated abilities if cantActivate is true
if (choice == null) { // can't find anything left
if (!sa.isMinTargetChosen() || sa.isZeroTargets()) {
sa.resetTargets();
return new AiAbilityDecision(0, AiPlayDecision.CantPlayAi);
} else {
if (!ComputerUtil.shouldCastLessThanMax(ai, sa.getHostCard())) {
return new AiAbilityDecision(0, AiPlayDecision.CantPlayAi);
}
break;
}
}
list.remove(choice);
oppCreatures.remove(choice);
sa.getTargets().add(choice);
}
return new AiAbilityDecision(100, AiPlayDecision.WillPlay);
}
return new AiAbilityDecision(0, AiPlayDecision.CantPlayAi);
} else { //no AILogic
return new AiAbilityDecision(0, AiPlayDecision.CantPlayAi);
}

View File

@@ -501,19 +501,6 @@ public class PumpAi extends PumpAiBase {
}
}
// Detain target nonland permanent: don't target noncreature permanents that don't have
// any activated abilities.
if ("DetainNonLand".equals(sa.getParam("AILogic"))) {
list = CardLists.filter(list, CardPredicates.CREATURES.or(card -> {
for (SpellAbility sa1 : card.getSpellAbilities()) {
if (sa1.isActivatedAbility()) {
return true;
}
}
return false;
}));
}
// Filter AI-specific targets if provided
list = ComputerUtil.filterAITgts(sa, ai, list, true);

View File

@@ -20,6 +20,19 @@ import java.util.function.Predicate;
public abstract class TapAiBase extends SpellAbilityAi {
Predicate<Card> CREATURE_OR_TAP_ABILITY = c -> {
if (c.isCreature()) {
return true;
}
for (final SpellAbility sa : c.getSpellAbilities()) {
if (sa.isAbility() && sa.getPayCosts().hasTapCost()) {
return true;
}
}
return false;
};
/**
* <p>
* tapTargetList.
@@ -102,34 +115,12 @@ public abstract class TapAiBase extends SpellAbilityAi {
final Game game = ai.getGame();
CardCollection tapList = CardLists.getTargetableCards(ai.getOpponents().getCardsIn(ZoneType.Battlefield), sa);
tapList = CardLists.filter(tapList, CardPredicates.CAN_TAP);
tapList = CardLists.filter(tapList, c -> {
if (c.isCreature()) {
return true;
}
for (final SpellAbility sa1 : c.getSpellAbilities()) {
if (sa1.isAbility() && sa1.getPayCosts().hasTapCost()) {
return true;
}
}
return false;
});
tapList = CardLists.filter(tapList, CREATURE_OR_TAP_ABILITY);
//use broader approach when the cost is a positive thing
if (tapList.isEmpty() && ComputerUtil.activateForCost(sa, ai)) {
tapList = CardLists.getTargetableCards(ai.getOpponents().getCardsIn(ZoneType.Battlefield), sa);
tapList = CardLists.filter(tapList, c -> {
if (c.isCreature()) {
return true;
}
for (final SpellAbility sa12 : c.getSpellAbilities()) {
if (sa12.isAbility() && sa12.getPayCosts().hasTapCost()) {
return true;
}
}
return false;
});
tapList = CardLists.filter(tapList, CREATURE_OR_TAP_ABILITY);
}
//try to exclude things that will already be tapped due to something on stack or because something is

View File

@@ -67,6 +67,7 @@ public enum ApiType {
Counter (CounterEffect.class),
DamageAll (DamageAllEffect.class),
DealDamage (DamageDealEffect.class),
Detain (DetainEffect.class),
DayTime (DayTimeEffect.class),
Debuff (DebuffEffect.class),
DelayedTrigger (DelayedTriggerEffect.class),

View File

@@ -0,0 +1,40 @@
package forge.game.ability.effects;
import java.util.EnumSet;
import forge.game.Game;
import forge.game.ability.SpellAbilityEffect;
import forge.game.card.Card;
import forge.game.card.CardCollection;
import forge.game.spellability.SpellAbility;
import forge.game.staticability.StaticAbility;
import forge.game.zone.ZoneType;
public class DetainEffect extends SpellAbilityEffect {
@Override
public void resolve(SpellAbility sa) {
Card source = sa.getHostCard();
final Game game = source.getGame();
CardCollection list = getTargetCards(sa);
if (list.isEmpty()) {
return;
}
Card eff = createEffect(sa, sa.getActivatingPlayer(), "Detain Effect", source.getImageKey());
eff.addRemembered(list);
// Add forgot trigger
addForgetOnMovedTrigger(eff, "Battlefield");
StaticAbility stAb = eff.addStaticAbility("Mode$ CantAttack,CantBlock,CantBeActivated | ValidCard$ Card.IsRemembered | Description$ Remembered can't attack or block and its activated abilities can't be activated.");
stAb.setActiveZone(EnumSet.of(ZoneType.Command));
stAb.setIntrinsic(true);
addUntilCommand(sa, exileEffectCommand(game, eff), "UntilYourNextTurn", sa.getActivatingPlayer());
game.getAction().moveToCommand(eff, sa);
}
}

View File

@@ -5,5 +5,6 @@ A:SP$ Charm | Choices$ DBNameCard,DBPump
SVar:DBNameCard:DB$ NameCard | Defined$ You | ValidCards$ Card.nonLand | ValidDescription$ nonland | SubAbility$ DBEffect | SpellDescription$ Choose a nonland card name. Until your next turn, your opponents can't cast spells with the chosen name.
SVar:DBEffect:DB$ Effect | StaticAbilities$ CantCast | Duration$ UntilYourNextTurn
SVar:CantCast:Mode$ CantBeCast | ValidCard$ Card.nonLand+NamedCard | Caster$ Opponent | Description$ Your opponents can't cast spells with the chosen name.
SVar:DBPump:DB$ Pump | ValidTgts$ Permanent.nonLand | TgtPrompt$ Choose target nonland permanent | KW$ HIDDEN CARDNAME can't attack or block. & HIDDEN CARDNAME's activated abilities can't be activated. | IsCurse$ True | Duration$ UntilYourNextTurn | AILogic$ DetainNonLand | SpellDescription$ Choose target nonland permanent. Until your next turn, it can't attack or block, and its activated abilities can't be activated.
SVar:DBPump:DB$ Effect | ValidTgts$ Permanent.nonLand | TgtPrompt$ Choose target nonland permanent | RememberObjects$ Targeted | StaticAbilities$ DBCantStatic | ForgetOnMoved$ Battlefield | IsCurse$ True | Duration$ UntilYourNextTurn | SpellDescription$ Choose target nonland permanent. Until your next turn, it can't attack or block, and its activated abilities can't be activated.
SVar:DBCantStatic:Mode$ CantAttack,CantBlock,CantBeActivated | ValidCard$ Card.IsRemembered | Description$ Remembered can't attack or block, and its activated abilities can't be activated..
Oracle:Choose one —\n• Choose a nonland card name. Opponents can't cast spells with the chosen name until your next turn.\n• Choose target nonland permanent. Until your next turn, it can't attack or block, and its activated abilities can't be activated.

View File

@@ -4,6 +4,6 @@ Types:Creature Archon
PT:4/5
K:Flying
T:Mode$ Attacks | TriggerZones$ Battlefield | ValidCard$ Card.Self | Execute$ Detain | TriggerDescription$ Whenever CARDNAME attacks, detain up to two target nonland permanents your opponents control. (Until your next turn, those permanents can't attack or block and their activated abilities can't be activated.)
SVar:Detain:DB$ Pump | TargetMin$ 0 | TargetMax$ 2 | KW$ HIDDEN CARDNAME can't attack or block. & HIDDEN CARDNAME's activated abilities can't be activated. | IsCurse$ True | ValidTgts$ Permanent.nonLand+OppCtrl | TgtPrompt$ Select target nonland permanent your opponent controls to detain. | Duration$ UntilYourNextTurn | AILogic$ DetainNonLand
SVar:Detain:DB$ Detain | TargetMin$ 0 | TargetMax$ 2 | ValidTgts$ Permanent.nonLand+OppCtrl | TgtPrompt$ Select target nonland permanent your opponent controls to detain.
SVar:HasAttackEffect:TRUE
Oracle:Flying\nWhenever Archon of the Triumvirate attacks, detain up to two target nonland permanents your opponents control. (Until your next turn, those permanents can't attack or block and their activated abilities can't be activated.)

View File

@@ -3,6 +3,6 @@ ManaCost:1 W
Types:Creature Human Soldier
PT:2/1
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ Detain | TriggerDescription$ When CARDNAME enters, detain target creature an opponent controls. (Until your next turn, that creature can't attack or block and its activated abilities can't be activated.)
SVar:Detain:DB$ Pump | KW$ HIDDEN CARDNAME can't attack or block. & HIDDEN CARDNAME's activated abilities can't be activated. | IsCurse$ True | Duration$ UntilYourNextTurn | ValidTgts$ Creature.OppCtrl | TgtPrompt$ Select target creature your opponent controls to detain.
SVar:Detain:DB$ Detain | ValidTgts$ Creature.OppCtrl | TgtPrompt$ Select target creature your opponent controls to detain.
SVar:PlayMain1:TRUE
Oracle:When Azorius Arrester enters, detain target creature an opponent controls. (Until your next turn, that creature can't attack or block and its activated abilities can't be activated.)

View File

@@ -3,6 +3,6 @@ ManaCost:2 W W
Types:Creature Human Wizard
PT:2/2
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ Detain | TriggerDescription$ When CARDNAME enters, detain up to two target creatures your opponents control. (Until your next turn, those creatures can't attack or block and their activated abilities can't be activated.)
SVar:Detain:DB$ Pump | TargetMin$ 0 | TargetMax$ 2 | KW$ HIDDEN CARDNAME can't attack or block. & HIDDEN CARDNAME's activated abilities can't be activated. | IsCurse$ True | Duration$ UntilYourNextTurn | ValidTgts$ Creature.OppCtrl | TgtPrompt$ Select target creature your opponent controls to detain. | AILogic$ DetainNonLand
SVar:Detain:DB$ Detain | TargetMin$ 0 | TargetMax$ 2 | ValidTgts$ Creature.OppCtrl | TgtPrompt$ Select target creature your opponent controls to detain.
SVar:PlayMain1:TRUE
Oracle:When Azorius Justiciar enters, detain up to two target creatures your opponents control. (Until your next turn, those creatures can't attack or block and their activated abilities can't be activated.)

View File

@@ -3,9 +3,7 @@ ManaCost:3
Types:Artifact
A:AB$ Pump | Cost$ 1 T | ValidTgts$ Creature | TgtPrompt$ Select target creature | KW$ HIDDEN CARDNAME can't attack. | SubAbility$ DBPutCounter | IsCurse$ True | SpellDescription$ Target creature can't attack this turn. Put a brick counter on CARDNAME.
SVar:DBPutCounter:DB$ PutCounter | Defined$ Self | CounterType$ BRICK | CounterNum$ 1
A:AB$ Effect | Cost$ 1 T | ValidTgts$ Creature | TgtPrompt$ Select target creature | RememberObjects$ Targeted | StaticAbilities$ DBCantAttack,DBCantBlockBy,DBCantBeActivated | ForgetOnMoved$ Battlefield | IsCurse$ True | Duration$ UntilYourNextTurn | CheckSVar$ X | SVarCompare$ GE3 | SpellDescription$ Until your next turn, target creature can't attack or block and its activated abilities can't be activated. Activate only if there are three or more brick counters on CARDNAME.
SVar:DBCantAttack:Mode$ CantAttack | ValidCard$ Card.IsRemembered | Description$ Remembered can't attack or block.
SVar:DBCantBlockBy:Mode$ CantBlockBy | ValidBlocker$ Card.IsRemembered | Secondary$ True | Description$ Remembered can't attack or block.
SVar:DBCantBeActivated:Mode$ CantBeActivated | ValidCard$ Card.IsRemembered | Description$ Remembered activated abilities can't be activated.
A:AB$ Effect | Cost$ 1 T | ValidTgts$ Creature | TgtPrompt$ Select target creature | RememberObjects$ Targeted | StaticAbilities$ DBCantStatic | ForgetOnMoved$ Battlefield | IsCurse$ True | Duration$ UntilYourNextTurn | CheckSVar$ X | SVarCompare$ GE3 | SpellDescription$ Until your next turn, target creature can't attack or block and its activated abilities can't be activated. Activate only if there are three or more brick counters on CARDNAME.
SVar:DBCantStatic:Mode$ CantAttack,CantBlock,CantBeActivated | ValidCard$ Card.IsRemembered | Description$ Remembered can't attack or block and activated abilities can't be activated.
SVar:X:Count$CardCounters.BRICK
Oracle:{1}, {T}: Target creature can't attack this turn. Put a brick counter on Edifice of Authority.\n{1}, {T}: Until your next turn, target creature can't attack or block and its activated abilities can't be activated. Activate only if there are three or more brick counters on Edifice of Authority.

View File

@@ -3,7 +3,9 @@ ManaCost:2 W W
Types:Legendary Planeswalker Bahamut
Loyalty:3
S:Mode$ Continuous | Affected$ Card.Self | IsPresent$ Card.Self+counters_GE7_LOYALTY | AddKeyword$ Flying & Indestructible | AddType$ Creature & Dragon & God | SetPower$ 7 | SetToughness$ 7 | RemoveCardTypes$ True | CharacteristicDefining$ True | Description$ As long as CARDNAME has seven or more loyalty counters on him, he's a 7/7 Dragon God creature with flying and indestructible.
A:AB$ Pump | Cost$ AddCounter<1/LOYALTY> | Planeswalker$ True | ValidTgts$ Creature.withoutFirst Strike+withoutDouble Strike+withoutVigilance | TgtPrompt$ Target creature without first strike, double strike, or vigilance | KW$ HIDDEN CARDNAME can't attack or block. | IsCurse$ True | Duration$ UntilYourNextTurn | AILogic$ DetainNonLand | SpellDescription$ Target creature without first strike, double strike, or vigilance can't attack or block until your next turn.
A:AB$ Effect | Cost$ AddCounter<1/LOYALTY> | Planeswalker$ True | ValidTgts$ Creature.withoutFirst Strike+withoutDouble Strike+withoutVigilance | TgtPrompt$ Target creature without first strike, double strike, or vigilance | RememberObjects$ Targeted | StaticAbilities$ DBCantAttack,DBCantBlockBy | ForgetOnMoved$ Battlefield | IsCurse$ True | Duration$ UntilYourNextTurn | SpellDescription$ Target creature without first strike, double strike, or vigilance can't attack or block until your next turn.
SVar:DBCantAttack:Mode$ CantAttack | ValidCard$ Card.IsRemembered | Description$ Remembered can't attack or block.
SVar:DBCantBlockBy:Mode$ CantBlockBy | ValidBlocker$ Card.IsRemembered | Secondary$ True | Description$ Remembered can't attack or block.
A:AB$ ChangeZone | Cost$ AddCounter<1/LOYALTY> | Planeswalker$ True | Origin$ Library | OriginAlternative$ Graveyard | Destination$ Hand | ChangeType$ Card.YouOwn+namedMonk of the Open Hand | ChangeNum$ 1 | Optional$ True | ShuffleNonMandatory$ True | SpellDescription$ Search your library and/or graveyard for a card named Monk of the Open Hand, reveal it, and put it into your hand. If you search your library this way, shuffle.
DeckHas:Type$Dragon|God
DeckHints:Name$Monk of the Open Hand

View File

@@ -1,6 +1,6 @@
Name:Inaction Injunction
ManaCost:1 U
Types:Sorcery
A:SP$ Pump | ValidTgts$ Creature.OppCtrl | TgtPrompt$ Select target creature your opponent controls to detain. | KW$ HIDDEN CARDNAME can't attack or block. & HIDDEN CARDNAME's activated abilities can't be activated. | IsCurse$ True | Duration$ UntilYourNextTurn | SubAbility$ DBDraw | SpellDescription$ Detain target creature an opponent controls. (Until your next turn, that creature can't attack or block and its activated abilities can't be activated.)
A:SP$ Detain | ValidTgts$ Creature.OppCtrl | TgtPrompt$ Select target creature your opponent controls to detain. | SubAbility$ DBDraw | SpellDescription$ Detain target creature an opponent controls. (Until your next turn, that creature can't attack or block and its activated abilities can't be activated.)
SVar:DBDraw:DB$ Draw | NumCards$ 1 | SpellDescription$ Draw a card.
Oracle:Detain target creature an opponent controls. (Until your next turn, that creature can't attack or block and its activated abilities can't be activated.)\nDraw a card.

View File

@@ -4,6 +4,6 @@ Types:Creature Vedalken Knight
PT:3/3
K:Flying
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ Detain | TriggerDescription$ When CARDNAME enters, detain target creature an opponent controls. (Until your next turn, that creature can't attack or block and its activated abilities can't be activated.)
SVar:Detain:DB$ Pump | KW$ HIDDEN CARDNAME can't attack or block. & HIDDEN CARDNAME's activated abilities can't be activated. | IsCurse$ True | Duration$ UntilYourNextTurn | ValidTgts$ Creature.OppCtrl | TgtPrompt$ Select target creature your opponent controls to detain.
SVar:Detain:DB$ Detain | ValidTgts$ Creature.OppCtrl | TgtPrompt$ Select target creature your opponent controls to detain.
SVar:PlayMain1:TRUE
Oracle:Flying\nWhen Isperia's Skywatch enters, detain target creature an opponent controls. (Until your next turn, that creature can't attack or block and its activated abilities can't be activated.)

View File

@@ -5,7 +5,8 @@ Loyalty:3
T:Mode$ DamageDoneOnce | CombatDamage$ True | ValidSource$ Creature.YouCtrl | TriggerZones$ Battlefield | ValidTarget$ Player | Execute$ TrigLoyalty | TriggerDescription$ Whenever one or more creatures you control deal combat damage to a player, you may return one of them to its owner's hand. If you do, you may activate loyalty abilities of NICKNAME twice this turn rather than only once.
SVar:TrigLoyalty:AB$ Effect | Cost$ Return<1/Card.TriggeredSources> | StaticAbilities$ PWTwice
SVar:PWTwice:Mode$ NumLoyaltyAct | ValidCard$ Card.EffectSource | Twice$ True | Description$ You may activate the loyalty abilities of NICKNAME twice this turn rather than only once.
A:AB$ Pump | Cost$ AddCounter<1/LOYALTY> | Planeswalker$ True | TargetMin$ 0 | TargetMax$ 1 | ValidTgts$ Creature | TgtPrompt$ Select up to one target creature | KW$ HIDDEN CARDNAME can't attack or block. | IsCurse$ True | Duration$ UntilYourNextTurn | AILogic$ DetainNonLand | StackDescription$ {c:Targeted} can't attack or block until your next turn. | SpellDescription$ Up to one target creature can't attack or block until your next turn.
A:AB$ Effect | Cost$ AddCounter<1/LOYALTY> | Planeswalker$ True | TargetMin$ 0 | TargetMax$ 1 | ValidTgts$ Creature | TgtPrompt$ Select up to one target creature | RememberObjects$ Targeted | StaticAbilities$ DBCantAttackBlock | ForgetOnMoved$ Battlefield | IsCurse$ True | Duration$ UntilYourNextTurn | StackDescription$ {c:Targeted} can't attack or block until your next turn. | SpellDescription$ Up to one target creature can't attack or block until your next turn.
SVar:DBCantAttackBlock:Mode$ CantAttack,CantBlock | ValidCard$ Card.IsRemembered | Description$ Remembered can't attack or block.
A:AB$ Draw | Cost$ AddCounter<0/LOYALTY> | NumCards$ 1 | Planeswalker$ True | SpellDescription$ Draw a card.
A:AB$ Token | Cost$ SubCounter<2/LOYALTY> | Planeswalker$ True | TokenScript$ c_2_2_a_drone_deathtouch_leavedrain | SpellDescription$ Create a 2/2 colorless Drone artifact creature token with deathtouch and "When this creature leaves the battlefield, each opponent loses 2 life and you gain 2 life."
DeckHas:Ability$Token|LifeGain & Type$Artifact|Drone

View File

@@ -6,9 +6,9 @@ R:Event$ Counter | ValidCard$ Card.Self | ValidSA$ Spell | Layer$ CantHappen | D
T:Mode$ Phase | Phase$ Upkeep | TriggerZones$ Battlefield | Execute$ TrigToken | TriggerDescription$ At the beginning of each upkeep, create a 1/1 Phyrexian Serpent Squirrel artifact creature token named Toski's Coil with "Whenever this creature deals combat damage to a player, draw a card."
SVar:TrigToken:DB$ Token | TokenAmount$ 1 | TokenScript$ toskis_coil | TokenOwner$ You
A:AB$ Charm | Cost$ Sac<1/Serpent.Other;Squirrel.Other/another Serpent or Squirrel> | Choices$ DBEffect,DBPump
SVar:DBEffect:DB$ Effect | ValidTgts$ Creature | RememberObjects$ Targeted | ExileOnMoved$ Battlefield | StaticAbilities$ MustAttack | SubAbility$ DBConstrict | SpellDescription$ Target creature attacks this turn if able. Its activated abilities can't be activated this turn.
SVar:DBEffect:DB$ Effect | ValidTgts$ Creature | RememberObjects$ Targeted | ExileOnMoved$ Battlefield | StaticAbilities$ MustAttack,DBCantBeActivated | SpellDescription$ Target creature attacks this turn if able. Its activated abilities can't be activated this turn.
SVar:MustAttack:Mode$ MustAttack | ValidCreature$ Card.IsRemembered | Description$ This creature attacks this turn if able.
SVar:DBConstrict:DB$ Pump | Defined$ ParentTarget | KW$ HIDDEN CARDNAME's activated abilities can't be activated. | StackDescription$ None
SVar:DBCantBeActivated:Mode$ CantBeActivated | ValidCard$ Card.IsRemembered | Description$ Remembered activated abilities can't be activated.
SVar:DBPump:DB$ Pump | Defined$ Self | KW$ Indestructible | SpellDescription$ CARDNAME gains indestructible until end of turn.
DeckHas:Ability$Token|Sacrifice & Type$Artifact
Oracle:This spell can't be countered.\nAt the beginning of each upkeep, create a 1/1 Phyrexian Serpent Squirrel artifact creature token named Toski's Coil with "Whenever this creature deals combat damage to a player, draw a card."\nSacrifice another Serpent or Squirrel: Choose one —\n• Target creature attacks this turn if able. Its activated abilities can't be activated this turn.\n• Koma and Toski, Compleated gains indestructible until end of turn.

View File

@@ -4,6 +4,6 @@ Types:Legendary Creature Human Soldier
PT:4/4
K:Protection from red
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ Detain | TriggerDescription$ When CARDNAME enters, detain each nonland permanent your opponents control with mana value 4 or less.
SVar:Detain:DB$ PumpAll | KW$ HIDDEN CARDNAME can't attack or block. & HIDDEN CARDNAME's activated abilities can't be activated. | IsCurse$ True | Duration$ UntilYourNextTurn | ValidCards$ Permanent.OppCtrl+nonLand+cmcLE4
SVar:Detain:DB$ Detain | Defined$ Valid Permanent.OppCtrl+nonLand+cmcLE4
SVar:PlayMain1:TRUE
Oracle:Protection from red\nWhen Lavinia of the Tenth enters, detain each nonland permanent your opponents control with mana value 4 or less. (Until your next turn, those permanents can't attack or block and their activated abilities can't be activated.)

View File

@@ -4,7 +4,8 @@ Types:Legendary Creature Angel Wizard
PT:3/3
K:Flying
T:Mode$ Phase | Phase$ BeginCombat | ValidPlayer$ You | TriggerZones$ Battlefield | CheckSVar$ X | SVarCompare$ EQ4 | Execute$ TrigPump | TriggerDescription$ At the beginning of combat on your turn, if you have a full party, choose target nonland permanent an opponent controls. Until your next turn, it can't attack or block, and its activated abilities can't be activated.
SVar:TrigPump:DB$ Pump | ValidTgts$ Permanent.nonLand+OppCtrl | TgtPrompt$ Choose target nonland permanent an opponent controls | KW$ HIDDEN CARDNAME can't attack or block. & HIDDEN CARDNAME's activated abilities can't be activated. | IsCurse$ True | Duration$ UntilYourNextTurn | AILogic$ DetainNonLand
SVar:TrigPump:DB$ Effect | ValidTgts$ Permanent.nonLand+OppCtrl | TgtPrompt$ Choose target nonland permanent an opponent controls | RememberObjects$ Targeted | StaticAbilities$ DBCantStatic | ForgetOnMoved$ Battlefield | IsCurse$ True | Duration$ UntilYourNextTurn
SVar:DBCantStatic:Mode$ CantAttack,CantBlock,CantBeActivated | ValidCard$ Card.IsRemembered | Description$ Remembered can't attack or block, and its activated abilities can't be activated.
A:AB$ Pump | Cost$ Sac<1/NICKNAME> | Defined$ Valid Creature.YouCtrl | KWChoice$ Hexproof,Indestructible | StackDescription$ {p:You} chooses hexproof or indestructible. Creatures {p:You} controls gain that ability until end of turn. | SpellDescription$ Choose hexproof or indestructible. Creatures you control gain that ability until end of turn.
SVar:X:Count$Party
SVar:BuffedBy:Rogue,Warrior,Wizard

View File

@@ -1,5 +1,5 @@
Name:Lyev Decree
ManaCost:1 W
Types:Sorcery
A:SP$ Pump | TargetMin$ 0 | TargetMax$ 2 | KW$ HIDDEN CARDNAME can't attack or block. & HIDDEN CARDNAME's activated abilities can't be activated. | IsCurse$ True | ValidTgts$ Creature.OppCtrl | TgtPrompt$ Select target creature your opponent controls to detain. | Duration$ UntilYourNextTurn | SpellDescription$ Detain up to two target creatures your opponents control. (Until your next turn, those permanents can't attack or block and their activated abilities can't be activated.)
A:SP$ Detain | TargetMin$ 0 | TargetMax$ 2 | ValidTgts$ Creature.OppCtrl | TgtPrompt$ Select target creature your opponent controls to detain. | SpellDescription$ Detain up to two target creatures your opponents control. (Until your next turn, those permanents can't attack or block and their activated abilities can't be activated.)
Oracle:Detain up to two target creatures your opponents control. (Until your next turn, those creatures can't attack or block and their activated abilities can't be activated.)

View File

@@ -4,6 +4,6 @@ Types:Creature Human Knight
PT:3/1
K:Flying
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ Detain | TriggerDescription$ When CARDNAME enters, detain target nonland permanent an opponent controls. (Until your next turn, that permanent can't attack or block and its activated abilities can't be activated.)
SVar:Detain:DB$ Pump | KW$ HIDDEN CARDNAME can't attack or block. & HIDDEN CARDNAME's activated abilities can't be activated. | IsCurse$ True | Duration$ UntilYourNextTurn | ValidTgts$ Permanent.nonLand+OppCtrl | TgtPrompt$ Select target nonland permanent an opponent controls | AILogic$ DetainNonLand
SVar:Detain:DB$ Detain | ValidTgts$ Permanent.nonLand+OppCtrl | TgtPrompt$ Select target nonland permanent an opponent controls
SVar:PlayMain1:TRUE
Oracle:Flying\nWhen Lyev Skyknight enters, detain target nonland permanent an opponent controls. (Until your next turn, that permanent can't attack or block and its activated abilities can't be activated.)

View File

@@ -2,5 +2,5 @@ Name:Martial Law
ManaCost:2 W W
Types:Enchantment
T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ Detain | TriggerDescription$ At the beginning of your upkeep, detain target creature an opponent controls. (Until your next turn, that creature can't attack or block and its activated abilities can't be activated.)
SVar:Detain:DB$ Pump | KW$ HIDDEN CARDNAME can't attack or block. & HIDDEN CARDNAME's activated abilities can't be activated. | IsCurse$ True | Duration$ UntilYourNextTurn | ValidTgts$ Creature.OppCtrl | TgtPrompt$ Select target creature your opponent controls to detain.
SVar:Detain:DB$ Detain | ValidTgts$ Creature.OppCtrl | TgtPrompt$ Select target creature your opponent controls to detain.
Oracle:At the beginning of your upkeep, detain target creature an opponent controls. (Until your next turn, that creature can't attack or block and its activated abilities can't be activated.)

View File

@@ -2,5 +2,6 @@ Name:Mythos of Vadrok
ManaCost:2 R R
Types:Sorcery
A:SP$ DealDamage | ValidTgts$ Creature,Planeswalker | TgtPrompt$ Select any number of target creatures or planeswalkers to distribute damage to | NumDmg$ 5 | TargetMin$ 0 | TargetMax$ 5 | DividedAsYouChoose$ 5 | SubAbility$ DBPump | StackDescription$ SpellDescription | SpellDescription$ CARDNAME deals 5 damage divided as you choose among any number of target creatures and/or planeswalkers. If {W}{U} was spent to cast this spell, until your next turn, those permanents can't attack or block and their activated abilities can't be activated.
SVar:DBPump:DB$ Pump | Defined$ Targeted | Duration$ UntilYourNextTurn | KW$ HIDDEN CARDNAME can't attack or block. & HIDDEN CARDNAME's activated abilities can't be activated. | ConditionManaSpent$ W U | StackDescription$ None
SVar:DBPump:DB$ Effect | RememberObjects$ Targeted | StaticAbilities$ DBCantStatic | ForgetOnMoved$ Battlefield | IsCurse$ True | Duration$ UntilYourNextTurn | ConditionManaSpent$ W U | StackDescription$ None
SVar:DBCantStatic:Mode$ CantAttack,CantBlock,CantBeActivated | ValidCard$ Card.IsRemembered | Description$ Remembered can't attack or block and its activated abilities can't be activated.
Oracle:Mythos of Vadrok deals 5 damage divided as you choose among any number of target creatures and/or planeswalkers. If {W}{U} was spent to cast this spell, until your next turn, those permanents can't attack or block and their activated abilities can't be activated.

View File

@@ -3,5 +3,5 @@ ManaCost:W U
Types:Creature Human Wizard
PT:2/2
A:AB$ Pump | Cost$ W U | ValidTgts$ Creature | TgtPrompt$ Select target creature | KW$ Flying | SpellDescription$ Target creature gains flying until end of turn.
A:AB$ Pump | Cost$ 3 W U | ValidTgts$ Permanent.nonLand+OppCtrl | TgtPrompt$ Select target nonland permanent your opponent controls to detain. | KW$ HIDDEN CARDNAME can't attack or block. & HIDDEN CARDNAME's activated abilities can't be activated. | IsCurse$ True | Duration$ UntilYourNextTurn | AILogic$ DetainNonLand | SpellDescription$ Detain target nonland permanent an opponent controls. (Until your next turn, that permanent can't attack or block and its activated abilities can't be activated.)
A:AB$ Detain | Cost$ 3 W U | ValidTgts$ Permanent.nonLand+OppCtrl | TgtPrompt$ Select target nonland permanent your opponent controls to detain. | SpellDescription$ Detain target nonland permanent an opponent controls. (Until your next turn, that permanent can't attack or block and its activated abilities can't be activated.)
Oracle:{W}{U}: Target creature gains flying until end of turn.\n{3}{W}{U}: Detain target nonland permanent an opponent controls. (Until your next turn, that permanent can't attack or block and its activated abilities can't be activated.)

View File

@@ -4,6 +4,6 @@ Types:Creature Spirit
PT:2/1
S:Mode$ CantBlockBy | ValidAttacker$ Creature.Self | Description$ CARDNAME can't be blocked.
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ Detain | TriggerDescription$ When CARDNAME enters, detain target creature an opponent controls. (Until your next turn, that creature can't attack or block and its activated abilities can't be activated.)
SVar:Detain:DB$ Pump | KW$ HIDDEN CARDNAME can't attack or block. & HIDDEN CARDNAME's activated abilities can't be activated. | IsCurse$ True | Duration$ UntilYourNextTurn | ValidTgts$ Creature.OppCtrl | TgtPrompt$ Select target creature your opponent controls to detain.
SVar:Detain:DB$ Detain | ValidTgts$ Creature.OppCtrl | TgtPrompt$ Select target creature your opponent controls to detain.
SVar:PlayMain1:TRUE
Oracle:Soulsworn Spirit can't be blocked.\nWhen Soulsworn Spirit enters, detain target creature an opponent controls. (Until your next turn, that creature can't attack or block and its activated abilities can't be activated.)

View File

@@ -3,5 +3,5 @@ ManaCost:no cost
Types:Plane Unknown Planet
S:Mode$ Continuous | Affected$ Creature.YouOwn | AffectedZone$ Graveyard | AddKeyword$ Escape:CardManaCost ExileFromGrave<3/Card.Other/other> | EffectZone$ Command | Description$ Each creature card in your graveyard has escape. The escape cost is equal to the card's mana cost plus exile three other cards from your graveyard. (You may cast cards from your graveyard for their escape cost.)
T:Mode$ ChaosEnsues | TriggerZones$ Command | Execute$ TrigDetain | TriggerDescription$ Whenever chaos ensues, detain target creature an opponent controls. (Until your next turn, that creature can't attack or block and its activated abilities can't be activated.)
SVar:TrigDetain:DB$ Pump | KW$ HIDDEN CARDNAME can't attack or block. & HIDDEN CARDNAME's activated abilities can't be activated. | IsCurse$ True | Duration$ UntilYourNextTurn | ValidTgts$ Creature.OppCtrl | TgtPrompt$ Select target creature your opponent controls to detain.
SVar:TrigDetain:DB$ Detain | ValidTgts$ Creature.OppCtrl | TgtPrompt$ Select target creature your opponent controls to detain.
Oracle:Each creature card in your graveyard has escape. The escape cost is equal to the card's mana cost plus exile three other cards from your graveyard. (You may cast cards from your graveyard for their escape cost.)\nWhenever chaos ensues, detain target creature an opponent controls. (Until your next turn, that creature can't attack or block and its activated abilities can't be activated.)

View File

@@ -6,5 +6,5 @@ T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.S
SVar:TrigCharm:DB$ Charm | Choices$ DBTax,DBDetain
SVar:DBTax:DB$ Effect | Duration$ UntilYourNextTurn | StaticAbilities$ RaiseCost | SpellDescription$ Until your next turn, spells your opponents cast cost {1} more to cast.
SVar:RaiseCost:Mode$ RaiseCost | ValidCard$ Card | Activator$ Opponent | Type$ Spell | Amount$ 1 | Description$ Spells your opponents cast cost {1} more to cast.
SVar:DBDetain:DB$ Pump | KW$ HIDDEN CARDNAME can't attack or block. & HIDDEN CARDNAME's activated abilities can't be activated. | IsCurse$ True | Duration$ UntilYourNextTurn | ValidTgts$ Creature.OppCtrl | TgtPrompt$ Select target creature your opponent controls to detain. | SpellDescription$ Arrest — Detain target creature an opponent controls. (Until your next turn, that creature can't attack or block and its activated abilities can't be activated.)
SVar:DBDetain:DB$ Detain | ValidTgts$ Creature.OppCtrl | TgtPrompt$ Select target creature your opponent controls to detain. | SpellDescription$ Arrest — Detain target creature an opponent controls. (Until your next turn, that creature can't attack or block and its activated abilities can't be activated.)
Oracle:When Tax Collector enters, choose one —\n• Tax — Until your next turn, spells your opponents cast cost {1} more to cast.\n• Arrest — Detain target creature an opponent controls. (Until your next turn, that creature can't attack or block and its activated abilities can't be activated.)