Implemented support for MustBeBlockedByAtLeastOne...Effect. (ongoing).

This commit is contained in:
LevelX2 2013-09-17 17:25:16 +02:00
parent 3a048cb828
commit 3dd75d6609
5 changed files with 61 additions and 11 deletions

View file

@ -30,9 +30,8 @@ package mage.sets.darkascension;
import java.util.UUID;
import mage.constants.*;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.combat.MustBeBlockedByAllSourceEffect;
import mage.abilities.effects.common.combat.MustBeBlockedByAtLeastOneTargetEffect;
import mage.abilities.effects.common.continious.GainAbilityTargetEffect;
import mage.abilities.keyword.DeathtouchAbility;
import mage.abilities.keyword.FlashbackAbility;
@ -51,9 +50,9 @@ public class DeadlyAllure extends CardImpl<DeadlyAllure> {
this.color.setBlack(true);
// Target creature gains deathtouch until end of turn and must be blocked this turn if able.
this.getSpellAbility().addEffect(new GainAbilityTargetEffect(new SimpleStaticAbility(Zone.BATTLEFIELD, new MustBeBlockedByAllSourceEffect()), Duration.EndOfTurn));
// Target creature gains deathtouch until end of turn and must be blocked this turn if able.
this.getSpellAbility().addEffect(new GainAbilityTargetEffect(DeathtouchAbility.getInstance(), Duration.EndOfTurn));
this.getSpellAbility().addEffect(new MustBeBlockedByAtLeastOneTargetEffect(Duration.EndOfTurn));
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
// Flashback {G}

View file

@ -28,16 +28,14 @@
package mage.sets.riseoftheeldrazi;
import java.util.UUID;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.DrawCardControllerEffect;
import mage.abilities.effects.common.combat.MustBeBlockedByAllSourceEffect;
import mage.abilities.effects.common.combat.MustBeBlockedByAtLeastOneTargetEffect;
import mage.abilities.effects.common.continious.GainAbilityTargetEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.target.common.TargetCreaturePermanent;

View file

@ -81,7 +81,7 @@ public class MustBeBlockedByAtLeastOneSourceEffect extends RequirementEffect<Mus
@Override
public boolean applies(Permanent permanent, Ability source, Game game) {
return true;
return permanent.canBlock(source.getSourceId(), game);
}
@Override

View file

@ -37,6 +37,9 @@ import mage.game.permanent.Permanent;
/**
* !! This effect does only support one target.
*
*
* http://tappedout.net/mtg-questions/must-be-blocked-if-able-effect-makes-other-attacking-creatures-essentially-unblockable/
*
* When you Declare Blockers, you choose an arrangement for your blockers,
@ -81,7 +84,7 @@ public class MustBeBlockedByAtLeastOneTargetEffect extends RequirementEffect<Mus
@Override
public boolean applies(Permanent permanent, Ability source, Game game) {
return true;
return permanent.canBlock(this.getTargetPointer().getFirst(game, source), game);
}
@Override

View file

@ -340,11 +340,31 @@ public class Combat implements Serializable, Copyable<Combat> {
public boolean checkBlockRequirementsAfter(Player player, Player controller, Game game) {
//20101001 - 509.1c
// check mustBeBlockedByAtLeastOne
Map<UUID, Set<UUID>> mustBeBlockedByAtLeastOne = new HashMap<UUID, Set<UUID>>();
// check mustBlockAny
for (Permanent creature : game.getBattlefield().getActivePermanents(new FilterControlledCreaturePermanent(), player.getId(), game)) {
// Does the creature not block and is an opponent of the attacker
if (creature.getBlocking() == 0 && game.getOpponents(attackerId).contains(creature.getControllerId())) {
// get all requiremet effects that apply to the creature
for (RequirementEffect effect : game.getContinuousEffects().getApplicableRequirementEffects(creature, game).keySet()) {
for (Map.Entry entry : game.getContinuousEffects().getApplicableRequirementEffects(creature, game).entrySet()) {
RequirementEffect effect = (RequirementEffect)entry.getKey();
// get possible mustBeBlockedByAtLeastOne blocker
for (Ability ability: (HashSet<Ability>)entry.getValue()) {
UUID toBeBlockedCreature = effect.mustBlockAttackerIfElseUnblocked(ability, game);
if (toBeBlockedCreature != null) {
Set<UUID> potentialBlockers;
if (mustBeBlockedByAtLeastOne.containsKey(toBeBlockedCreature)) {
potentialBlockers = mustBeBlockedByAtLeastOne.get(toBeBlockedCreature);
} else {
potentialBlockers = new HashSet<UUID>();
mustBeBlockedByAtLeastOne.put(toBeBlockedCreature, potentialBlockers);
}
potentialBlockers.add(creature.getId());
}
}
// check the mustBlockAny
if (effect.mustBlockAny(game)) {
// check that it can block at least one of the attackers
@ -376,6 +396,36 @@ public class Combat implements Serializable, Copyable<Combat> {
}
}
}
// check mustBeBlockedByAtLeastOne
// TODO: Check if already blocking creatures that block other creatures have no madatory block and have to block here
for (UUID toBeBlockedCreatureId: mustBeBlockedByAtLeastOne.keySet()) {
for (CombatGroup combatGroup : game.getCombat().getGroups()) {
if (combatGroup.getBlockers().isEmpty() && combatGroup.getAttackers().contains(toBeBlockedCreatureId)) {
// creature is not blocked but has possible blockers
if (controller.isHuman()) {
Permanent toBeBlockedCreature = game.getPermanent(toBeBlockedCreatureId);
if (toBeBlockedCreature != null) {
game.informPlayer(controller, new StringBuilder(toBeBlockedCreature.getName()).append(" has to be blocked by at least one creature.").toString());
}
return false;
} else {
// take the first potential blocker from the set to block for the AI
UUID blockingCreatureId = mustBeBlockedByAtLeastOne.get(toBeBlockedCreatureId).iterator().next();
Permanent blockingCreature = game.getPermanent(blockingCreatureId);
if (blockingCreature != null) {
Player defender = game.getPlayer(blockingCreature.getControllerId());
if (defender != null) {
defender.declareBlocker(defender.getId(), blockingCreatureId, toBeBlockedCreatureId, game);
}
}
}
}
}
}
return true;
}