@Override public void watch(GameEvent event, Game game) { if (event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD) { Permanent perm = game.getPermanent(event.getTargetId()); if (perm.getCardType().contains(CardType.LAND)) { Integer amount = amountOfLandsPlayedThisTurn.get(perm.getControllerId()); if (amount == null) { amount = Integer.valueOf(1); } else { ++amount; } amountOfLandsPlayedThisTurn.put(perm.getControllerId(), amount); } } }
@Override public boolean apply(Game game, Ability source) { Permanent sourcePermanent = (Permanent) game.getLastKnownInformation( targetPointer.getFirst(game, source), Constants.Zone.BATTLEFIELD); if (sourcePermanent == null) { return false; } Player controller = game.getPlayer(source.getControllerId()); if (controller == null) { return false; } Cards revealed = new CardsImpl(); Card artifactCard = null; Cards nonArtifactCards = new CardsImpl(); Player player = game.getPlayer(sourcePermanent.getControllerId()); while (artifactCard == null && player.getLibrary().size() > 0) { Card card = player.getLibrary().removeFromTop(game); revealed.add(card); if (card.getCardType().contains(CardType.ARTIFACT)) artifactCard = card; else nonArtifactCards.add(card); } player.revealCards("Shape Anew", revealed, game); if (artifactCard != null) { artifactCard.putOntoBattlefield( game, Constants.Zone.LIBRARY, source.getId(), player.getId()); } player.getLibrary().addAll(nonArtifactCards.getCards(game), game); player.shuffleLibrary(game); return true; }
public void assignDamageToBlockers(boolean first, Game game) { if (attackers.size() > 0 && (!first || hasFirstOrDoubleStrike(game))) { if (blockers.isEmpty()) { unblockedDamage(first, game); } else { Permanent attacker = game.getPermanent(attackers.get(0)); if (attacker .getAbilities() .containsKey(DamageAsThoughNotBlockedAbility.getInstance().getId())) { Player player = game.getPlayer(attacker.getControllerId()); if (player.chooseUse( Outcome.Damage, "Do you wish to assign damage for " + attacker.getLogName() + " as though it weren't blocked?", game)) { blocked = false; unblockedDamage(first, game); } } if (blockers.size() == 1) { singleBlockerDamage(first, game); } else { multiBlockerDamage(first, game); } } } }
/** * Damages attacking creatures by a creature that blocked several ones Damages only attackers as * blocker was damage in either {@link #singleBlockerDamage} or {@link #multiBlockerDamage}. * * <p>Handles abilities like "{this} an block any number of creatures.". * * @param first * @param game */ private void multiAttackerDamage(boolean first, Game game) { Permanent blocker = game.getPermanent(blockers.get(0)); if (blocker == null) { return; } Player player = game.getPlayer(blocker.getControllerId()); int damage = getDamageValueFromPermanent(blocker, game); if (canDamage(blocker, first)) { Map<UUID, Integer> assigned = new HashMap<>(); for (UUID attackerId : attackerOrder) { Permanent attacker = game.getPermanent(attackerId); int lethalDamage; if (blocker.getAbilities().containsKey(DeathtouchAbility.getInstance().getId())) { lethalDamage = 1; } else { lethalDamage = attacker.getToughness().getValue() - attacker.getDamage(); } if (lethalDamage >= damage) { assigned.put(attackerId, damage); break; } int damageAssigned = player.getAmount( lethalDamage, damage, "Assign damage to " + attacker.getLogName(), game); assigned.put(attackerId, damageAssigned); damage -= damageAssigned; } for (Map.Entry<UUID, Integer> entry : assigned.entrySet()) { Permanent attacker = game.getPermanent(entry.getKey()); attacker.markDamage(entry.getValue(), blocker.getId(), game, true, true); } } }
@Override public boolean checkTrigger(GameEvent event, Game game) { if (event.getType() == GameEvent.EventType.DAMAGED_PLAYER) { if (((DamagedEvent) event).isCombatDamage()) { Permanent creature = game.getPermanent(event.getSourceId()); if (creature != null && creature.getControllerId().equals(controllerId) && !damagedPlayerIds.contains(event.getTargetId())) { damagedPlayerIds.add(event.getTargetId()); return true; } } } if (event.getType().equals(GameEvent.EventType.END_COMBAT_STEP_POST)) { damagedPlayerIds.clear(); } if (event.getType().equals(GameEvent.EventType.ZONE_CHANGE) && event.getTargetId().equals(getSourceId())) { ZoneChangeEvent zEvent = (ZoneChangeEvent) event; if (zEvent.getFromZone().equals(Zone.GRAVEYARD)) { damagedPlayerIds.clear(); } } return false; }
@Override public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) { Permanent permanent = game.getPermanent(sourceId); if (permanent != null && permanent.getControllerId().equals(source.getControllerId())) { return true; } return false; }
@Override public boolean canAttack(UUID defenderId, Ability source, Game game) { if (defenderId.equals(source.getControllerId())) { return false; } Permanent planeswalker = game.getPermanent(defenderId); return planeswalker == null || !planeswalker.getControllerId().equals(source.getControllerId()); }
@Override public boolean checkTrigger(GameEvent event, Game game) { if (event.getType() == GameEvent.EventType.TAPPED) { Permanent p = game.getPermanent(event.getTargetId()); if (p != null && p.getCardType().contains(CardType.CREATURE)) { if (game.getOpponents(this.controllerId).contains(p.getControllerId())) return true; } } return false; }
@Override public boolean canBeBlocked(Permanent attacker, Permanent blocker, Ability source, Game game) { // check if all creatures of defender are able to block this permanent // permanent.canBlock() can't be used because causing recursive call for (Permanent permanent : game.getBattlefield().getAllActivePermanents(filter, blocker.getControllerId(), game)) { if (permanent.isTapped() && !game.getState() .getContinuousEffects() .asThough( this.getId(), AsThoughEffectType.BLOCK_TAPPED, source, blocker.getControllerId(), game)) { return false; } // check blocker restrictions for (Map.Entry<RestrictionEffect, HashSet<Ability>> entry : game.getContinuousEffects().getApplicableRestrictionEffects(permanent, game).entrySet()) { for (Ability ability : entry.getValue()) { if (!entry.getKey().canBlock(attacker, permanent, ability, game)) { return false; } } } // check also attacker's restriction effects for (Map.Entry<RestrictionEffect, HashSet<Ability>> restrictionEntry : game.getContinuousEffects().getApplicableRestrictionEffects(attacker, game).entrySet()) { for (Ability ability : restrictionEntry.getValue()) { if (!(restrictionEntry.getKey() instanceof CantBeBlockedUnlessAllEffect) && !restrictionEntry.getKey().canBeBlocked(attacker, permanent, ability, game)) { return false; } } } if (attacker.hasProtectionFrom(permanent, game)) { return false; } } return true; }
private UUID getSourceControllerId(UUID sourceId, Game game) { StackObject source = game.getStack().getStackObject(sourceId); if (source != null) { return source.getControllerId(); } Permanent permanent = game.getBattlefield().getPermanent(sourceId); if (permanent != null) { return permanent.getControllerId(); } return null; }
@Override public boolean apply(Game game, Ability source) { Set<UUID> opponents = game.getOpponents(source.getControllerId()); for (Permanent perm : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), game)) { if (opponents.contains(perm.getControllerId())) { perm.getAbilities().remove(FlyingAbility.getInstance()); } } return true; }
@Override public boolean applies(GameEvent event, Ability source, Game game) { Permanent permanent = game.getPermanent(event.getTargetId()); if (permanent == null) { permanent = game.getPermanentEntering(event.getTargetId()); } if (permanent != null && permanent.getControllerId().equals(source.getControllerId())) { return true; } return false; }
public boolean canBlock(Permanent blocker, Game game) { // player can't block if another player is attacked if (!defendingPlayerId.equals(blocker.getControllerId())) { return false; } for (UUID attackerId : attackers) { if (!blocker.canBlock(attackerId, game)) { return false; } } return true; }
@Override public boolean apply(Game game, Ability source) { Permanent targetedLand = game.getPermanent(source.getFirstTarget()); if (targetedLand != null) { targetedLand.destroy(source.getSourceId(), game, true); Player controller = game.getPlayer(targetedLand.getControllerId()); if (controller != null) { controller.damage(2, source.getSourceId(), game, false, true); } return true; } return false; }
@Override public boolean apply(Game game, Ability source) { Permanent permanent = (Permanent) game.getLastKnownInformation(source.getFirstTarget(), Zone.BATTLEFIELD); if (permanent != null && !permanent.getSupertype().contains("Basic")) { Player player = game.getPlayer(permanent.getControllerId()); if (player != null) { player.damage(2, source.getSourceId(), game, false, true); return true; } } return false; }
@Override public boolean apply(Game game, Ability source) { Permanent permanent = (Permanent) game.getLastKnownInformation(source.getFirstTarget(), Zone.BATTLEFIELD); if (permanent != null) { Player player = game.getPlayer(permanent.getControllerId()); if (player != null) { player.gainLife(permanent.getToughness().getValue(), game); return true; } } return false; }
@Override public void watch(GameEvent event, Game game) { if (condition == true) { // no need to check - condition has already occured return; } if (event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD) { Permanent permanent = game.getPermanent(event.getTargetId()); if (permanent.getCardType().contains(CardType.LAND) && permanent.getControllerId().equals(this.controllerId)) { condition = true; } } }
@Override public boolean apply(Game game, Ability source) { Permanent enchantment = game.getPermanent(source.getSourceId()); if (enchantment != null) { Permanent creature = game.getPermanent(enchantment.getAttachedTo()); if (creature != null) { if (filter.match(creature, source.getSourceId(), enchantment.getControllerId(), game)) { return true; } } } return false; }
@Override public boolean apply(Game game, Ability source) { Permanent permanent = game.getPermanent(source.getFirstTarget()); if (permanent != null) { Player player = game.getPlayer(permanent.getControllerId()); if (player != null) { permanent.damage(4, source.getSourceId(), game, true, false); player.damage(2, source.getSourceId(), game, false, true); return true; } } return false; }
@Override public boolean apply(Game game, Ability source) { Permanent permanent = game.getPermanentOrLKIBattlefield(this.getTargetPointer().getFirst(game, source)); if (permanent != null) { Player controller = game.getPlayer(permanent.getControllerId()); if (controller != null) { int amount = permanent.getPower().getValue(); controller.damage(amount, source.getSourceId(), game, false, true); return true; } } return false; }
@Override public boolean checkTrigger(GameEvent event, Game game) { if (event.getType() == GameEvent.EventType.DRAW_STEP_PRE) { switch (targetController) { case YOU: boolean yours = event.getPlayerId().equals(this.controllerId); if (yours) { if (getTargets().size() == 0) { for (Effect effect : this.getEffects()) { effect.setTargetPointer(new FixedTarget(event.getPlayerId())); } } } return yours; case OPPONENT: if (game.getOpponents(this.controllerId).contains(event.getPlayerId())) { if (getTargets().size() == 0) { for (Effect effect : this.getEffects()) { effect.setTargetPointer(new FixedTarget(event.getPlayerId())); } } return true; } case CONTROLLER_ATTACHED_TO: Permanent attachment = game.getPermanent(sourceId); if (attachment != null && attachment.getAttachedTo() != null) { Permanent attachedTo = game.getPermanent(attachment.getAttachedTo()); if (attachedTo != null && attachedTo.getControllerId().equals(event.getPlayerId())) { if (getTargets().size() == 0) { for (Effect effect : this.getEffects()) { effect.setTargetPointer(new FixedTarget(event.getPlayerId())); } } return true; } } break; case ANY: if (getTargets().size() == 0) { for (Effect effect : this.getEffects()) { effect.setTargetPointer(new FixedTarget(event.getPlayerId())); } } return true; } } return false; }
@Override public boolean checkTrigger(GameEvent event, Game game) { if ((event.getType() == EventType.DAMAGED_PLAYER && event.getTargetId().equals(this.getControllerId())) && ((DamagedEvent) event).isCombatDamage()) { return true; } if (event.getType() == EventType.DAMAGED_PLANESWALKER && ((DamagedEvent) event).isCombatDamage()) { Permanent permanent = game.getPermanent(event.getTargetId()); if (permanent != null && permanent.getControllerId().equals(this.getControllerId())) { return true; } } return false; }
private void singleBlockerDamage(boolean first, Game game) { // TODO: handle banding Permanent blocker = game.getPermanent(blockers.get(0)); Permanent attacker = game.getPermanent(attackers.get(0)); if (blocker != null && attacker != null) { int blockerDamage = getDamageValueFromPermanent( blocker, game); // must be set before attacker damage marking because of effects like Test of // Faith if (blocked && canDamage(attacker, first)) { int damage = getDamageValueFromPermanent(attacker, game); if (hasTrample(attacker)) { int lethalDamage; if (attacker.getAbilities().containsKey(DeathtouchAbility.getInstance().getId())) { lethalDamage = 1; } else { lethalDamage = blocker.getToughness().getValue() - blocker.getDamage(); } if (lethalDamage >= damage) { blocker.markDamage(damage, attacker.getId(), game, true, true); } else { Player player = game.getPlayer(attacker.getControllerId()); int damageAssigned = player.getAmount( lethalDamage, damage, "Assign damage to " + blocker.getLogName(), game); blocker.markDamage(damageAssigned, attacker.getId(), game, true, true); damage -= damageAssigned; if (damage > 0) { defenderDamage(attacker, damage, game); } } } else { blocker.markDamage(damage, attacker.getId(), game, true, true); } } if (canDamage(blocker, first)) { if (blocker.getBlocking() == 1) { // blocking several creatures handled separately attacker.markDamage(blockerDamage, blocker.getId(), game, true, true); } } } }
@Override public boolean checkTrigger(GameEvent event, Game game) { if (((ZoneChangeEvent) event).getToZone() == Zone.GRAVEYARD && ((ZoneChangeEvent) event).getFromZone() == Zone.BATTLEFIELD) { Permanent permanent = (Permanent) game.getLastKnownInformation(event.getTargetId(), Zone.BATTLEFIELD); if (permanent != null && permanent.getControllerId().equals(this.getControllerId()) && permanent.getCardType().contains(CardType.CREATURE)) { this.getTargets().clear(); this.addTarget(new TargetControlledCreaturePermanent()); this.getEffects().clear(); this.addEffect( new AddCountersTargetEffect( CounterType.P1P1.createInstance(permanent.getPower().getValue()))); return true; } } return false; }
@Override public boolean checkTrigger(GameEvent event, Game game) { if (event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD) { if (!event.getTargetId().equals(this.getSourceId())) { Permanent triggeringCreature = game.getPermanent(event.getTargetId()); if (triggeringCreature != null && triggeringCreature.getCardType().contains(CardType.CREATURE) && triggeringCreature.getControllerId().equals(this.controllerId)) { Permanent sourceCreature = game.getPermanent(sourceId); if (sourceCreature != null && isPowerOrThoughnessGreater(sourceCreature, triggeringCreature)) { this.getEffects().get(0).setTargetPointer(new FixedTarget(event.getTargetId())); return true; } } } } return false; }
@Override public boolean apply(Game game, Ability source) { Permanent permanent = game.getPermanent(source.getSourceId()); if (permanent != null) { permanent.addCounters(CounterType.DESPAIR.createInstance(), game); int count = permanent.getCounters().getCount(CounterType.DESPAIR); if (count > 0) { Player controller = game.getPlayer(permanent.getControllerId()); if (controller != null) { for (UUID playerId : controller.getInRange()) { Player player = game.getPlayer(playerId); if (player != null) { exileCards(player, count, source, game); } } } } } return false; }
@Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { DragonOnTheBattlefieldWhileSpellWasCastWatcher watcher = (DragonOnTheBattlefieldWhileSpellWasCastWatcher) game.getState().getWatchers().get("DragonOnTheBattlefieldWhileSpellWasCastWatcher"); if (watcher != null && watcher.castWithConditionTrue(source.getId())) { Permanent permanent = game.getPermanentOrLKIBattlefield(getTargetPointer().getFirst(game, source)); if (permanent != null) { Player player = game.getPlayer(permanent.getControllerId()); if (player != null) { player.damage(3, source.getSourceId(), game, false, true); } } } return true; } return false; }
@Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { Set<UUID> toSacrifice = new HashSet<UUID>(); if (controller.flipCoin(game)) { // each blocking creature is sacrificed by its controller for (CombatGroup combatGroup : game.getCombat().getGroups()) { for (UUID blockerId : combatGroup.getBlockers()) { toSacrifice.add(blockerId); } } } else { // each blocked creature is sacrificed by its controller for (CombatGroup combatGroup : game.getCombat().getGroups()) { if (!combatGroup.getBlockers().isEmpty()) { for (UUID attackerId : combatGroup.getAttackers()) { toSacrifice.add(attackerId); } } } } for (UUID creatureId : toSacrifice) { Permanent creature = game.getPermanent(creatureId); if (creature != null) { creature.sacrifice(source.getSourceId(), game); Player player = game.getPlayer(creature.getControllerId()); if (player != null) { game.informPlayers( new StringBuilder(player.getName()) .append(" sacrifices ") .append(creature.getName()) .toString()); } } } return true; } return false; }
@Override public boolean canBeBlockedCheckAfter(Permanent attacker, Ability source, Game game) { for (CombatGroup combatGroup : game.getCombat().getGroups()) { if (combatGroup.getAttackers().contains(source.getSourceId())) { for (UUID blockerId : combatGroup.getBlockers()) { Permanent blockingCreature = game.getPermanent(blockerId); if (blockingCreature != null) { for (Permanent permanent : game.getBattlefield() .getAllActivePermanents( new FilterCreaturePermanent(), blockingCreature.getControllerId(), game)) { if (!combatGroup.getBlockers().contains(permanent.getId())) { // not all creatures block Tromokratis return false; } } } } } } return true; }
@Override public boolean checkTrigger(GameEvent event, Game game) { if (event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD) { Permanent permanent = game.getPermanent(event.getTargetId()); if (permanent.getCardType().contains(CardType.CREATURE) && (permanent.getControllerId().equals(this.controllerId))) { if (!this.getTargets().isEmpty()) { // remove previous target if (this.getTargets().get(0).getTargets().size() > 0) { this.getTargets().clear(); this.addTarget(new TargetCreaturePermanent()); } Target target = this.getTargets().get(0); if (target instanceof TargetCreaturePermanent) { target.add(event.getTargetId(), game); } } return true; } } return false; }