create generic CannotBeBlockedByPermanent and CannotBeBlockedExceptByPermanent abilities

master
melvin 2014-08-28 14:59:25 +08:00
parent 6c5cf13022
commit 0541d31bca
7 changed files with 93 additions and 107 deletions

View File

@ -1,25 +0,0 @@
[
new MagicBattalionTrigger() {
@Override
public MagicEvent executeTrigger(
final MagicGame game,
final MagicPermanent permanent,
final MagicPermanent attacker) {
return new MagicEvent(
permanent,
this,
"Creatures PN controls gain first strike and trample until end of turn and can't be blocked by creature tokens this turn."
);
}
@Override
public void executeEvent(final MagicGame game, final MagicEvent event) {
final Collection<MagicPermanent> creatures=
game.filterPermanents(event.getPlayer(),MagicTargetFilterFactory.CREATURE_YOU_CONTROL);
for (final MagicPermanent creature : creatures) {
game.doAction(new MagicGainAbilityAction(creature,MagicAbility.FirstStrike));
game.doAction(new MagicGainAbilityAction(creature,MagicAbility.Trample));
game.doAction(new MagicGainAbilityAction(creature,MagicAbility.CannotBeBlockedByTokens));
}
}
}
]

View File

@ -6,7 +6,7 @@ type=Creature
subtype=Goblin,Soldier
cost={R}
pt=1/1
ability=haste
ability=haste;\
Whenever SN and at least two other creatures attack, creatures you control gain first strike, trample, and can't be blocked by creature tokens until end of turn.
timing=main
requires_groovy_code
oracle=Haste. Battalion — Whenever Legion Loyalist and at least two other creatures attack, creatures you control gain first strike and trample until end of turn and can't be blocked by creature tokens this turn.

View File

@ -26,19 +26,6 @@ public enum MagicAbility {
CannotAttack("(SN )?can't attack(\\.)?",-50),
CannotAttackOrBlock("(SN )?can't attack or block(\\.)?",-200),
CannotBlockWithoutFlying("(SN )?can block only creatures with flying\\.",-40),
CannotBeBlockedByFlying("(SN )?can't be blocked by creatures with flying\\.",20),
CannotBeBlockedExceptWithFlying("(SN )?can't be blocked except by creatures with flying\\.",30),
CannotBeBlockedExceptWithFlyingOrReach("(SN )?can't be blocked except by creatures with flying or reach\\.",25),
CannotBeBlockedExceptBySliver("(SN )?can't be blocked except by Slivers\\.",90),
CannotBeBlockedExceptByWalls("(SN )?can't be blocked except by Walls\\.",80),
CannotBeBlockedByWalls("(SN )?can't be blocked by Walls(\\.)?",10),
CannotBeBlockedByHumans("(SN )?can't be blocked by Humans\\.",10),
CannotBeBlockedByBlack("(SN )?can't be blocked by black creatures\\.",10),
CannotBeBlockedByBlue("(SN )?can't be blocked by blue creatures\\.",10),
CannotBeBlockedByGreen("(SN )?can't be blocked by green creatures\\.",10),
CannotBeBlockedByRed("(SN )?can't be blocked by red creatures\\.",10),
CannotBeBlockedByWhite("(SN )?can't be blocked by white creatures\\.",10),
CannotBeBlockedByTokens("(SN )?can't be blocked by creature tokens\\.",10),
CanBlockShadow("(SN )?can block creatures with shadow as though (they didn't have shadow|SN had shadow)\\.",10),
CannotBeCountered("(SN )?can't be countered( by spells or abilities)?\\.",0),
Hexproof("hexproof(\\.)?",80),
@ -64,15 +51,6 @@ public enum MagicAbility {
Indestructible("indestructible(\\.)?",150),
Haste("haste(\\.)?",0),
Lifelink("lifelink(\\.)?",40),
ProtectionFromBlack("(protection )?from black(\\.)?",20),
ProtectionFromBlue("(protection )?from blue(\\.)?",20),
ProtectionFromGreen("(protection )?from green(\\.)?",20),
ProtectionFromRed("(protection )?from red(\\.)?",20),
ProtectionFromWhite("(protection )?from white(\\.)?",20),
ProtectionFromMonoColored("protection from monocolored",50),
ProtectionFromAllColors("protection from all colors(\\.)?",150),
ProtectionFromColoredSpells("protection from colored spells",100),
ProtectionFromEverything("protection from everything",200),
Reach("reach(\\.)?",20),
Shadow("shadow(\\.)?",30),
Shroud("shroud(\\.)?",60),
@ -86,7 +64,37 @@ public enum MagicAbility {
Horsemanship("horsemanship(\\.)?",60),
Soulbond("soulbond",30),
CantActivateAbilities("can't activate abilities(\\.)?|its activated abilities can't be activated(\\.)?",-20),
ProtectionFromBlack("(protection )?from black(\\.)?",20),
ProtectionFromBlue("(protection )?from blue(\\.)?",20),
ProtectionFromGreen("(protection )?from green(\\.)?",20),
ProtectionFromRed("(protection )?from red(\\.)?",20),
ProtectionFromWhite("(protection )?from white(\\.)?",20),
ProtectionFromMonoColored("protection from monocolored",50),
ProtectionFromAllColors("protection from all colors(\\.)?",150),
ProtectionFromColoredSpells("protection from colored spells",100),
ProtectionFromEverything("protection from everything",200),
ProtectionFromPermanent("protection from " + ARG.WORDRUN + "(\\.)?", 10) {
protected void addAbilityImpl(final MagicAbilityStore card, final Matcher arg) {
card.add(MagicProtectionTrigger.create(
MagicTargetFilterFactory.multiple(ARG.wordrun(arg))
));
}
},
CannotBeBlockedByPermanent("(SN )?can't be blocked by " + ARG.WORDRUN + "(\\.)?", 10) {
protected void addAbilityImpl(final MagicAbilityStore card, final Matcher arg) {
card.add(MagicCannotBeBlockedTrigger.create(
MagicTargetFilterFactory.multiple(ARG.wordrun(arg))
));
}
},
CannotBeBlockedExceptByPermanent("(SN )?can't be blocked except by " + ARG.WORDRUN + "(\\.)?", 10) {
protected void addAbilityImpl(final MagicAbilityStore card, final Matcher arg) {
card.add(MagicCannotBeBlockedTrigger.createExcept(
MagicTargetFilterFactory.multiple(ARG.wordrun(arg))
));
}
},
Undying("undying",60) {
protected void addAbilityImpl(final MagicAbilityStore card, final Matcher arg) {
card.add(MagicUndyingTrigger.create());
@ -1192,13 +1200,6 @@ public enum MagicAbility {
));
}
},
ProtectionFromPermanent("protection from " + ARG.WORDRUN + "(\\.)?", 10) {
protected void addAbilityImpl(final MagicAbilityStore card, final Matcher arg) {
card.add(MagicProtectionTrigger.create(
MagicTargetFilterFactory.multiple(ARG.wordrun(arg))
));
}
}
;
public static final Set<MagicAbility> PROTECTION_FLAGS = EnumSet.range(ProtectionFromBlack, ProtectionFromEverything);

View File

@ -921,18 +921,7 @@ public class MagicPermanent extends MagicObjectImpl implements MagicSource,Magic
} else if (hasAbility(MagicAbility.Shadow)) {
return false;
}
// Flying
if (attacker.hasAbility(MagicAbility.CannotBeBlockedByFlying) &&
hasAbility(MagicAbility.Flying)) {
return false;
}
if (attacker.hasAbility(MagicAbility.CannotBeBlockedExceptWithFlying) &&
!hasAbility(MagicAbility.Flying)) {
return false;
}
if (!attacker.hasAbility(MagicAbility.Flying) &&
hasAbility(MagicAbility.CannotBlockWithoutFlying)) {
return false;
@ -945,51 +934,18 @@ public class MagicPermanent extends MagicObjectImpl implements MagicSource,Magic
return false;
}
if (attacker.hasAbility(MagicAbility.CannotBeBlockedExceptWithFlyingOrReach) &&
!hasAbility(MagicAbility.Flying) &&
!hasAbility(MagicAbility.Reach)) {
return false;
}
// Horsemanship
if (attacker.hasAbility(MagicAbility.Horsemanship) &&
!hasAbility(MagicAbility.Horsemanship)) {
return false;
}
// Subtype
if (attacker.hasAbility(MagicAbility.CannotBeBlockedByHumans) &&
hasSubType(MagicSubType.Human)) {
return false;
}
if (attacker.hasAbility(MagicAbility.CannotBeBlockedByWalls) &&
hasSubType(MagicSubType.Wall)) {
return false;
}
if (attacker.hasAbility(MagicAbility.CannotBeBlockedExceptByWalls) &&
!hasSubType(MagicSubType.Wall)) {
return false;
}
if (attacker.hasAbility(MagicAbility.CannotBeBlockedExceptBySliver) &&
!hasSubType(MagicSubType.Sliver)) {
return false;
}
// Tokens
if (attacker.hasAbility(MagicAbility.CannotBeBlockedByTokens) &&
isToken()) {
return false;
}
// Can't be blocked by a color
for (final MagicColor color : MagicColor.values()) {
if (attacker.hasAbility(color.getCannotBeBlockedByAbility()) &&
hasColor(color)) {
return false;
for (MagicTrigger<?> trigger: attacker.getTriggers()) {
if (trigger.getType() == MagicTriggerType.CannotBeBlocked) {
final MagicTrigger<MagicPermanent> cannotBeBlocked = (MagicTrigger<MagicPermanent>)trigger;
if (cannotBeBlocked.accept(attacker, this)) {
return false;
}
}
}

View File

@ -1109,6 +1109,13 @@ public class MagicTargetFilterFactory {
}
};
public static final MagicPermanentFilterImpl CREATURE_WITH_FLYING_OR_REACH = new MagicPermanentFilterImpl() {
public boolean accept(final MagicGame game,final MagicPlayer player,final MagicPermanent target) {
return target.isCreature() &&
(target.hasAbility(MagicAbility.Flying) || target.hasAbility(MagicAbility.Reach));
}
};
public static final MagicPermanentFilterImpl CREATURE_WITHOUT_FLYING_OR_ISLANDWALK = new MagicPermanentFilterImpl() {
public boolean accept(final MagicGame game,final MagicPlayer player,final MagicPermanent target) {
return target.isCreature() &&
@ -2239,6 +2246,7 @@ public class MagicTargetFilterFactory {
single.put("creature with converted mana cost 3 or less", CREATURE_CONVERTED_3_OR_LESS);
single.put("creature with converted mana cost 2 or less", CREATURE_CONVERTED_2_OR_LESS);
single.put("creature with flying", CREATURE_WITH_FLYING);
single.put("creature with flying or reach", CREATURE_WITH_FLYING_OR_REACH);
single.put("blue or black creature with flying", BLUE_OR_BLACK_CREATURE_WITH_FLYING);
single.put("creature without flying", CREATURE_WITHOUT_FLYING);
single.put("creature with defender", CREATURE_WITH_DEFENDER);
@ -2463,6 +2471,7 @@ public class MagicTargetFilterFactory {
.replaceAll("\\bbeasts\\b", "beast")
.replaceAll("\\bdemons\\b", "demon")
.replaceAll("\\bdragons\\b", "dragon")
.replaceAll("\\bwalls\\b", "wall")
.replaceAll("\\band\\b", "or")
.replaceAll("\\bthem\\b", "it")
.replaceAll("\\bin your hand\\b", "from your hand")

View File

@ -0,0 +1,44 @@
package magic.model.trigger;
import magic.model.MagicGame;
import magic.model.MagicPermanent;
import magic.model.event.MagicEvent;
import magic.model.target.MagicTargetFilter;
public abstract class MagicCannotBeBlockedTrigger extends MagicTrigger<MagicPermanent> {
public MagicCannotBeBlockedTrigger(final int priority) {
super(priority);
}
public MagicCannotBeBlockedTrigger() {}
public MagicTriggerType getType() {
return MagicTriggerType.CannotBeBlocked;
}
public static MagicCannotBeBlockedTrigger create(final MagicTargetFilter<MagicPermanent> filter) {
return new MagicCannotBeBlockedTrigger() {
@Override
public boolean accept(final MagicPermanent permanent, final MagicPermanent other) {
return filter.accept(permanent.getGame(), permanent.getController(), other);
}
@Override
public MagicEvent executeTrigger(final MagicGame game,final MagicPermanent permanent, final MagicPermanent other) {
throw new RuntimeException(getClass() + " does not have an executeTrigger method");
}
};
}
public static MagicCannotBeBlockedTrigger createExcept(final MagicTargetFilter<MagicPermanent> filter) {
return new MagicCannotBeBlockedTrigger() {
@Override
public boolean accept(final MagicPermanent permanent, final MagicPermanent other) {
return filter.accept(permanent.getGame(), permanent.getController(), other) == false;
}
@Override
public MagicEvent executeTrigger(final MagicGame game,final MagicPermanent permanent, final MagicPermanent other) {
throw new RuntimeException(getClass() + " does not have an executeTrigger method");
}
};
}
}

View File

@ -39,6 +39,7 @@ public enum MagicTriggerType {
IfLifeWouldChange, // MagicChangeLifeAction
WhenClash, // MagicPlayer
Protection, // MagicPermanent
CannotBeBlocked, // MagicPermanent
;
public boolean usesStack() {