use of mage.abilities.effects.RestrictionEffect in project mage by magefree.
the class RagingRiverEffect method apply.
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
List<Permanent> left = new ArrayList<>();
List<Permanent> right = new ArrayList<>();
for (UUID defenderId : game.getCombat().getPlayerDefenders(game)) {
Player defender = game.getPlayer(defenderId);
if (defender != null) {
List<Permanent> leftLog = new ArrayList<>();
List<Permanent> rightLog = new ArrayList<>();
FilterControlledCreaturePermanent filterBlockers = new FilterControlledCreaturePermanent("creatures without flying you control to assign to the \"left\" pile (creatures not chosen will be assigned to the \"right\" pile)");
filterBlockers.add(Predicates.not(new AbilityPredicate(FlyingAbility.class)));
Target target = new TargetControlledCreaturePermanent(0, Integer.MAX_VALUE, filterBlockers, true);
if (target.canChoose(source.getSourceId(), defenderId, game)) {
if (defender.chooseTarget(Outcome.Neutral, target, source, game)) {
for (Permanent permanent : game.getBattlefield().getAllActivePermanents(new FilterCreaturePermanent(), defenderId, game)) {
if (target.getTargets().contains(permanent.getId())) {
left.add(permanent);
leftLog.add(permanent);
} else if (filterBlockers.match(permanent, source.getSourceId(), defenderId, game)) {
right.add(permanent);
rightLog.add(permanent);
}
}
}
// it could be nice to invoke some graphic indicator of which creature is Left or Right in this spot
StringBuilder sb = new StringBuilder("Left pile of ").append(defender.getLogName()).append(": ");
sb.append(leftLog.stream().map(MageObject::getLogName).collect(Collectors.joining(", ")));
game.informPlayers(sb.toString());
sb = new StringBuilder("Right pile of ").append(defender.getLogName()).append(": ");
sb.append(rightLog.stream().map(MageObject::getLogName).collect(Collectors.joining(", ")));
game.informPlayers(sb.toString());
}
}
}
for (UUID attackers : game.getCombat().getAttackers()) {
Permanent attacker = game.getPermanent(attackers);
if (attacker != null && Objects.equals(attacker.getControllerId(), controller.getId())) {
CombatGroup combatGroup = game.getCombat().findGroup(attacker.getId());
if (combatGroup != null) {
FilterCreaturePermanent filter = new FilterCreaturePermanent();
Player defender = game.getPlayer(combatGroup.getDefendingPlayerId());
if (defender != null) {
if (left.isEmpty() && right.isEmpty()) {
// shortcut in case of no labeled blockers available
filter.add(Predicates.not(new AbilityPredicate(FlyingAbility.class)));
} else {
List<Permanent> leftLog = left.stream().filter(permanent -> permanent.getControllerId() != null).filter(permanent -> permanent.isControlledBy(defender.getId())).collect(Collectors.toList());
List<Permanent> rightLog = right.stream().filter(permanent -> permanent.getControllerId() != null).filter(permanent -> permanent.isControlledBy(defender.getId())).collect(Collectors.toList());
if (controller.choosePile(outcome, attacker.getName() + ": attacking " + defender.getName(), leftLog, rightLog, game)) {
filter.add(Predicates.not(Predicates.or(new AbilityPredicate(FlyingAbility.class), new PermanentInListPredicate(left))));
game.informPlayers(attacker.getLogName() + ": attacks left (" + defender.getLogName() + ")");
} else {
filter.add(Predicates.not(Predicates.or(new AbilityPredicate(FlyingAbility.class), new PermanentInListPredicate(right))));
game.informPlayers(attacker.getLogName() + ": attacks right (" + defender.getLogName() + ")");
}
}
RestrictionEffect effect = new CantBeBlockedByAllTargetEffect(filter, Duration.EndOfCombat);
effect.setTargetPointer(new FixedTarget(attacker.getId(), game));
game.addEffect(effect, source);
}
}
}
}
return true;
}
return false;
}
use of mage.abilities.effects.RestrictionEffect in project mage by magefree.
the class UntapSourceDuringEachOtherPlayersUntapStepEffect method apply.
@Override
public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) {
boolean applied = Boolean.TRUE.equals(game.getState().getValue(source.getSourceId() + "applied"));
if (!applied && layer == Layer.RulesEffects) {
if (!source.isControlledBy(game.getActivePlayerId()) && game.getStep() != null && game.getStep().getType() == PhaseStep.UNTAP) {
game.getState().setValue(source.getSourceId() + "applied", true);
Permanent permanent = game.getPermanent(source.getSourceId());
if (permanent != null) {
boolean untap = true;
for (RestrictionEffect effect : game.getContinuousEffects().getApplicableRestrictionEffects(permanent, game).keySet()) {
untap &= effect.canBeUntapped(permanent, source, game, true);
}
if (untap) {
permanent.untap(game);
}
}
}
} else if (applied && layer == Layer.RulesEffects) {
if (game.getStep() != null && game.getStep().getType() == PhaseStep.END_TURN) {
game.getState().setValue(source.getSourceId() + "applied", false);
}
}
return true;
}
use of mage.abilities.effects.RestrictionEffect in project mage by magefree.
the class PermanentImpl method getRules.
/**
* @param game can be null, e.g. for cards viewer
* @return
*/
@Override
public List<String> getRules(Game game) {
try {
List<String> rules = getRules();
// info
if (info != null) {
for (String data : info.values()) {
rules.add(data);
}
}
// ability hints
List<String> abilityHints = new ArrayList<>();
if (HintUtils.ABILITY_HINTS_ENABLE) {
for (Ability ability : getAbilities(game)) {
for (Hint hint : ability.getHints()) {
String s = hint.getText(game, ability);
if (s != null && !s.isEmpty()) {
abilityHints.add(s);
}
}
}
}
// restrict hints
List<String> restrictHints = new ArrayList<>();
if (game != null && HintUtils.RESTRICT_HINTS_ENABLE) {
// restrict
for (Map.Entry<RestrictionEffect, Set<Ability>> entry : game.getContinuousEffects().getApplicableRestrictionEffects(this, game).entrySet()) {
for (Ability ability : entry.getValue()) {
if (!entry.getKey().canAttack(game, false) || !entry.getKey().canAttack(this, null, ability, game, false)) {
restrictHints.add(HintUtils.prepareText("Can't attack" + addSourceObjectName(game, ability), null, HintUtils.HINT_ICON_RESTRICT));
}
if (!entry.getKey().canBlock(null, this, ability, game, false)) {
restrictHints.add(HintUtils.prepareText("Can't block" + addSourceObjectName(game, ability), null, HintUtils.HINT_ICON_RESTRICT));
}
if (!entry.getKey().canBeUntapped(this, ability, game, false)) {
restrictHints.add(HintUtils.prepareText("Can't untapped" + addSourceObjectName(game, ability), null, HintUtils.HINT_ICON_RESTRICT));
}
if (!entry.getKey().canUseActivatedAbilities(this, ability, game, false)) {
restrictHints.add(HintUtils.prepareText("Can't use activated abilities" + addSourceObjectName(game, ability), null, HintUtils.HINT_ICON_RESTRICT));
}
if (!entry.getKey().canTransform(this, ability, game, false)) {
restrictHints.add(HintUtils.prepareText("Can't transform" + addSourceObjectName(game, ability), null, HintUtils.HINT_ICON_RESTRICT));
}
}
}
// requirement
for (Map.Entry<RequirementEffect, Set<Ability>> entry : game.getContinuousEffects().getApplicableRequirementEffects(this, false, game).entrySet()) {
for (Ability ability : entry.getValue()) {
if (entry.getKey().mustAttack(game)) {
restrictHints.add(HintUtils.prepareText("Must attack" + addSourceObjectName(game, ability), null, HintUtils.HINT_ICON_REQUIRE));
}
if (entry.getKey().mustBlock(game)) {
restrictHints.add(HintUtils.prepareText("Must block" + addSourceObjectName(game, ability), null, HintUtils.HINT_ICON_REQUIRE));
}
if (entry.getKey().mustBlockAny(game)) {
restrictHints.add(HintUtils.prepareText("Must block any" + addSourceObjectName(game, ability), null, HintUtils.HINT_ICON_REQUIRE));
}
if (entry.getKey().mustBlockAllAttackers(game)) {
restrictHints.add(HintUtils.prepareText("Must block all attackers" + addSourceObjectName(game, ability), null, HintUtils.HINT_ICON_REQUIRE));
}
MageObject object = game.getObject(entry.getKey().mustAttackDefender(ability, game));
if (object != null) {
restrictHints.add(HintUtils.prepareText("Must attack defender " + object.getLogName() + addSourceObjectName(game, ability), null, HintUtils.HINT_ICON_REQUIRE));
}
object = game.getObject(entry.getKey().mustBlockAttacker(ability, game));
if (object != null) {
restrictHints.add(HintUtils.prepareText("Must block attacker " + object.getLogName() + addSourceObjectName(game, ability), null, HintUtils.HINT_ICON_REQUIRE));
}
object = game.getObject(entry.getKey().mustBlockAttackerIfElseUnblocked(ability, game));
if (object != null) {
restrictHints.add(HintUtils.prepareText("Must block attacker if able " + object.getLogName() + addSourceObjectName(game, ability), null, HintUtils.HINT_ICON_REQUIRE));
}
}
}
restrictHints.sort(String::compareTo);
}
// total hints
if (!abilityHints.isEmpty() || !restrictHints.isEmpty()) {
rules.add(HintUtils.HINT_START_MARK);
HintUtils.appendHints(rules, abilityHints);
HintUtils.appendHints(rules, restrictHints);
}
return rules;
} catch (Exception e) {
return CardUtil.RULES_ERROR_INFO;
}
}
use of mage.abilities.effects.RestrictionEffect in project mage by magefree.
the class WordOfCommandTestFlashEffect method apply.
@Override
public boolean apply(Game game, Ability source) {
Player sourceController = game.getPlayer(source.getControllerId());
Player targetPlayer = game.getPlayer(source.getFirstTarget());
MageObject sourceObject = game.getObject(source.getSourceId());
Card card = null;
if (sourceController != null && targetPlayer != null && sourceObject != null) {
Player controller = null;
Spell wordOfCommand = game.getSpell(source.getSourceId());
if (wordOfCommand != null) {
if (wordOfCommand.getCommandedBy() != null) {
controller = game.getPlayer(wordOfCommand.getCommandedBy());
} else {
controller = game.getPlayer(sourceController.getTurnControlledBy());
}
}
if (controller == null) {
// reset the controller to avoid NPE
controller = sourceController;
}
// Look at target opponent's hand and choose a card from it
TargetCard targetCard = new TargetCard(Zone.HAND, new FilterCard());
if (controller.choose(Outcome.Discard, targetPlayer.getHand(), targetCard, game)) {
card = game.getCard(targetCard.getFirstTarget());
}
// You control that player until Word of Command finishes resolving
CardUtil.takeControlUnderPlayerStart(game, controller, targetPlayer, true);
// The player plays that card if able
if (card != null) {
// While doing so, the player can activate mana abilities only if they're from lands that player controls
RestrictionEffect effect = new WordOfCommandCantActivateEffect();
effect.setTargetPointer(new FixedTarget(targetPlayer.getId()));
game.addEffect(effect, source);
// and only if mana they produce is spent to activate other mana abilities of lands they control and/or play that card
ManaPool manaPool = targetPlayer.getManaPool();
manaPool.setForcedToPay(true);
manaPool.storeMana();
int bookmark = game.bookmarkState();
boolean canPlay = checkPlayability(card, targetPlayer, game, source);
while (canPlay && targetPlayer.canRespond() && !targetPlayer.playCard(card, game, false, new ApprovingObject(source, game))) {
SpellAbility spellAbility = card.getSpellAbility();
if (spellAbility != null) {
spellAbility.getManaCostsToPay().clear();
spellAbility.getManaCostsToPay().addAll(spellAbility.getManaCosts());
// force rollback if card was deemed playable
((ManaCostsImpl) spellAbility.getManaCostsToPay()).forceManaRollback(game, manaPool);
canPlay = checkPlayability(card, targetPlayer, game, source);
} else {
break;
}
}
if (!canPlay) {
game.informPlayers(targetPlayer.getLogName() + " didn't play " + card.getLogName() + " (card can't be played)");
}
// duplicate in case of a new mana pool existing - probably not necessary, but just in case
manaPool.setForcedToPay(false);
// a rollback creates a new mana pool for the player, so it's necessary to find it again
manaPool = targetPlayer.getManaPool();
manaPool.setForcedToPay(false);
game.removeBookmark(bookmark);
targetPlayer.resetStoredBookmark(game);
for (RestrictionEffect eff : game.getContinuousEffects().getRestrictionEffects()) {
if (eff instanceof WordOfCommandCantActivateEffect) {
eff.discard();
break;
}
}
game.getContinuousEffects().removeInactiveEffects(game);
Spell spell = game.getSpell(card.getId());
if (spell != null) {
// If the chosen card is cast as a spell, you control the player while that spell is resolving
spell.setCommandedBy(controller.getId());
}
}
wordOfCommand = game.getSpell(source.getSourceId());
if (wordOfCommand != null) {
// You control the player until Word of Command finishes resolving
wordOfCommand.setCommandedBy(controller.getId());
} else {
CardUtil.takeControlUnderPlayerEnd(game, controller, targetPlayer);
}
return true;
}
return false;
}
use of mage.abilities.effects.RestrictionEffect in project mage by magefree.
the class TraceUtil method traceForPermanent.
private static void traceForPermanent(Game game, Permanent permanent, String uuid, ContinuousEffectsList<RestrictionEffect> restrictionEffects) {
for (RestrictionEffect effect : restrictionEffects) {
log.error(uuid + " effect=" + effect.toString() + " id=" + effect.getId());
for (Ability ability : restrictionEffects.getAbility(effect.getId())) {
if (!(ability instanceof StaticAbility) || ability.isInUseableZone(game, permanent, null)) {
log.error(uuid + " ability=" + ability + ", applies_to_attacker=" + effect.applies(permanent, ability, game));
} else {
boolean usable = ability.isInUseableZone(game, permanent, null);
log.error(uuid + " instanceof StaticAbility: " + (ability instanceof StaticAbility) + ", ability=" + ability);
log.error(uuid + " usable zone: " + usable + ", ability=" + ability);
if (!usable) {
Zone zone = ability.getZone();
log.error(uuid + " zone: " + zone);
MageObject object = game.getObject(ability.getSourceId());
log.error(uuid + " object: " + object);
if (object != null) {
log.error(uuid + " contains ability: " + object.getAbilities().contains(ability));
}
Zone test = game.getState().getZone(ability.getSourceId());
log.error(uuid + " test_zone: " + test);
}
}
}
}
}
Aggregations