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

View file

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

View file

@ -81,7 +81,7 @@ public class MustBeBlockedByAtLeastOneSourceEffect extends RequirementEffect<Mus
@Override @Override
public boolean applies(Permanent permanent, Ability source, Game game) { public boolean applies(Permanent permanent, Ability source, Game game) {
return true; return permanent.canBlock(source.getSourceId(), game);
} }
@Override @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/ * 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, * When you Declare Blockers, you choose an arrangement for your blockers,
@ -81,7 +84,7 @@ public class MustBeBlockedByAtLeastOneTargetEffect extends RequirementEffect<Mus
@Override @Override
public boolean applies(Permanent permanent, Ability source, Game game) { public boolean applies(Permanent permanent, Ability source, Game game) {
return true; return permanent.canBlock(this.getTargetPointer().getFirst(game, source), game);
} }
@Override @Override

View file

@ -340,11 +340,31 @@ public class Combat implements Serializable, Copyable<Combat> {
public boolean checkBlockRequirementsAfter(Player player, Player controller, Game game) { public boolean checkBlockRequirementsAfter(Player player, Player controller, Game game) {
//20101001 - 509.1c //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)) { for (Permanent creature : game.getBattlefield().getActivePermanents(new FilterControlledCreaturePermanent(), player.getId(), game)) {
// Does the creature not block and is an opponent of the attacker // Does the creature not block and is an opponent of the attacker
if (creature.getBlocking() == 0 && game.getOpponents(attackerId).contains(creature.getControllerId())) { if (creature.getBlocking() == 0 && game.getOpponents(attackerId).contains(creature.getControllerId())) {
// get all requiremet effects that apply to the creature // 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 // check the mustBlockAny
if (effect.mustBlockAny(game)) { if (effect.mustBlockAny(game)) {
// check that it can block at least one of the attackers // 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; return true;
} }