mirror of
https://github.com/correl/mage.git
synced 2024-11-15 19:19:33 +00:00
Implemented support for MustBeBlockedByAtLeastOne...Effect. (ongoing).
This commit is contained in:
parent
3a048cb828
commit
3dd75d6609
5 changed files with 61 additions and 11 deletions
|
@ -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;
|
||||||
|
@ -52,8 +51,8 @@ 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}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue