diff --git a/Mage.Sets/src/mage/sets/bornofthegods/Tromokratis.java b/Mage.Sets/src/mage/sets/bornofthegods/Tromokratis.java index aeceee4d8e6..83b9a0b70d1 100644 --- a/Mage.Sets/src/mage/sets/bornofthegods/Tromokratis.java +++ b/Mage.Sets/src/mage/sets/bornofthegods/Tromokratis.java @@ -44,7 +44,9 @@ import mage.constants.Duration; import mage.constants.Rarity; import mage.constants.Zone; import mage.filter.common.FilterAttackingOrBlockingCreature; +import mage.filter.common.FilterCreaturePermanent; import mage.game.Game; +import mage.game.combat.CombatGroup; import mage.game.permanent.Permanent; /** @@ -99,20 +101,29 @@ class CantBeBlockedUnlessAllEffect extends RestrictionEffect */ public abstract class RestrictionEffect> extends ContinuousEffectImpl { - private boolean notMoreThanRestriction; - private int notMoreThanNumber; - private FilterPermanent notMoreThanNumberFilter; - public RestrictionEffect(Duration duration) { - this(duration, false, 0, null); - } - - public RestrictionEffect(Duration duration, boolean notMoreThanRestriction, int notMoreThanNumber, FilterPermanent notMoreThanNumberFilter) { super(duration, Outcome.Detriment); - this.effectType = EffectType.RESTRICTION; - this.notMoreThanRestriction = notMoreThanRestriction; - this.notMoreThanNumber = notMoreThanNumber; - this.notMoreThanNumberFilter = notMoreThanNumberFilter; + this.effectType = EffectType.RESTRICTION; } public RestrictionEffect(final RestrictionEffect effect) { super(effect); - this.notMoreThanRestriction = effect.notMoreThanRestriction; - this.notMoreThanNumber = effect.notMoreThanNumber; - if (this.notMoreThanNumberFilter != null) { - this.notMoreThanNumberFilter = effect.notMoreThanNumberFilter.copy(); - } } @Override @@ -75,15 +58,6 @@ public abstract class RestrictionEffect> extends public abstract boolean applies(Permanent permanent, Ability source, Game game); - - /* - * only used for the notMoreThanRestrictions, called to check if the effect shall be applied for a player - * - */ - public boolean appliesNotMoreThan(Player player, Ability source, Game game) { - return false; - } - public boolean canAttack(Game game) { return true; } @@ -96,6 +70,18 @@ public abstract class RestrictionEffect> extends return true; } + /** + * Called for all attackers after all blocking decisions are made + * + * @param attacker + * @param source + * @param game + * @return true = block is ok fals = block is not valid (human: back to defining blockers, AI: remove blocker) + */ + public boolean canBeBlockedCheckAfter(Permanent attacker, Ability source, Game game) { + return true; + } + public boolean canBeUntapped(Permanent permanent, Game game) { return true; } @@ -103,17 +89,5 @@ public abstract class RestrictionEffect> extends public boolean canUseActivatedAbilities(Permanent permanent, Ability source, Game game) { return true; } - - public boolean isNotMoreThanRestriction() { - return notMoreThanRestriction; - } - - public int getNotMoreThanNumber() { - return notMoreThanNumber; - } - - public FilterPermanent getNotMoreThanNumberFilter() { - return notMoreThanNumberFilter; - } } diff --git a/Mage/src/mage/game/combat/Combat.java b/Mage/src/mage/game/combat/Combat.java index 93ff1c8019c..3acbca19a9f 100644 --- a/Mage/src/mage/game/combat/Combat.java +++ b/Mage/src/mage/game/combat/Combat.java @@ -38,6 +38,7 @@ import java.util.Set; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.effects.RequirementEffect; +import mage.abilities.effects.RestrictionEffect; import mage.abilities.keyword.CanAttackOnlyAloneAbility; import mage.abilities.keyword.CantAttackAloneAbility; import mage.abilities.keyword.VigilanceAbility; @@ -297,8 +298,9 @@ public class Combat implements Serializable, Copyable { /** * Handle the blocker selection process - * - * @param blockController player that controlls how to block, if null the defender is the controller + * + * @param blockController player that controlls how to block, if null the + * defender is the controller * @param game */ public void selectBlockers(Player blockController, Game game) { @@ -323,6 +325,9 @@ public class Combat implements Serializable, Copyable { } } choose = !this.checkBlockRequirementsAfter(defender, blockController, game); + if (!choose) { + choose = !this.checkBlockRestrictionsAfter(defender, blockController, game); + } } game.fireEvent(GameEvent.getEvent(GameEvent.EventType.DECLARED_BLOCKERS, defenderId, defenderId)); @@ -465,7 +470,7 @@ public class Combat implements Serializable, Copyable { // Creature is already blocking but not forced to do so if (creature.getBlocking() > 0) { - // get all requirement effects that apply to the creature (ce.g. is able to block attacker) + // get all requirement effects that apply to the creature (e.g. is able to block attacker) for (Map.Entry entry : game.getContinuousEffects().getApplicableRequirementEffects(creature, game).entrySet()) { RequirementEffect effect = (RequirementEffect) entry.getKey(); // get possible mustBeBlockedByAtLeastOne blocker @@ -657,6 +662,46 @@ public class Combat implements Serializable, Copyable { return true; } + /** + * Checks the canBeBlockedCheckAfter RestrictionEffect + * Is the block still valid after all block decisions are done + * + * @param player + * @param controller + * @param game + * @return + */ + public boolean checkBlockRestrictionsAfter(Player player, Player controller, Game game) { + for (UUID attackingCreatureId : this.getAttackers()) { + Permanent attackingCreature = game.getPermanent(attackingCreatureId); + if (attackingCreature != null) { + for (Map.Entry entry : game.getContinuousEffects().getApplicableRestrictionEffects(attackingCreature, game).entrySet()) { + RestrictionEffect effect = (RestrictionEffect) entry.getKey(); + for (Ability ability : (HashSet) entry.getValue()) { + if (!effect.canBeBlockedCheckAfter(attackingCreature, ability, game)) { + if (controller.isHuman()) { + game.informPlayer(controller, new StringBuilder(attackingCreature.getName()).append(" can't be blocked this way." ).toString()); + return false; + } else { + // remove blocking creatures for AI + for (CombatGroup combatGroup: this.getGroups()) { + if (combatGroup.getAttackers().contains(attackingCreatureId)) { + for(UUID blockerId :combatGroup.getBlockers()) { + removeBlocker(blockerId, game); + } + } + } + + } + } + } + } + } + } + return true; + } + + public void setDefenders(Game game) { Set opponents = game.getOpponents(attackerId); PlayerList players;