예제 #1
0
  /**
   * 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);
      }
    }
  }
예제 #2
0
 @Override
 public boolean apply(Game game, Ability source) {
   Player player = game.getPlayer(targetPointer.getFirst(game, source));
   if (player != null) {
     int cardsToDraw = amount.calculate(game, source);
     if (upTo) {
       cardsToDraw = player.getAmount(0, cardsToDraw, "Draw how many cards?", game);
     }
     if (!optional || player.chooseUse(outcome, "Use draw effect?", game)) {
       player.drawCards(cardsToDraw, game);
     }
     return true;
   }
   return false;
 }
예제 #3
0
 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 pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana) {
   Permanent permanent = game.getPermanent(sourceId);
   Player player = game.getPlayer(permanent.getControllerId());
   this.amountPaid =
       player.getAmount(
           minimalCountersToPay,
           permanent.getCounters().getCount(name),
           "Choose X counters to remove",
           game);
   if (this.amountPaid >= minimalCountersToPay) {
     permanent.removeCounters(name, amountPaid, game);
     this.paid = true;
   }
   game.informPlayers(
       player.getName()
           + " removes "
           + this.amountPaid
           + " "
           + name
           + " counter from "
           + permanent.getName());
   return paid;
 }
예제 #5
0
  @Override
  public boolean apply(Game game, Ability source) {
    Player controller = game.getPlayer(source.getControllerId());
    Card sourceCard = game.getCard(source.getSourceId());
    Map<UUID, Integer> payLife = new HashMap<>();
    int currentLifePaid;
    int totalPaidLife;
    if (controller != null) {
      PlayerList playerList = game.getState().getPlayerList().copy();
      while (!playerList.get().equals(source.getControllerId()) && controller.isInGame()) {
        playerList.getNext();
      }
      Player currentPlayer = game.getPlayer(playerList.get());
      UUID firstInactivePlayer = null;

      while (controller.isInGame()) {
        if (firstInactivePlayer == null) {
          firstInactivePlayer = currentPlayer.getId();
        }
        if (currentPlayer != null
            && currentPlayer.isInGame()
            && controller.getInRange().contains(currentPlayer.getId())) {
          currentLifePaid = 0;
          totalPaidLife = 0;
          if (currentPlayer.chooseUse(Outcome.AIDontUseIt, "Pay life?", source, game)) {
            totalPaidLife =
                currentPlayer.getAmount(0, controller.getLife(), "Pay how many life?", game);
            if (totalPaidLife > 0) {
              currentPlayer.loseLife(totalPaidLife, game);
              if (payLife.get(currentPlayer.getId()) == null) {
                payLife.put(currentPlayer.getId(), totalPaidLife);
              } else {
                currentLifePaid = payLife.get(currentPlayer.getId());
                payLife.put(currentPlayer.getId(), currentLifePaid + totalPaidLife);
              }
            }
            game.informPlayers(
                new StringBuilder(sourceCard.getName())
                    .append(": ")
                    .append(currentPlayer.getLogName())
                    .append(" pays ")
                    .append(payLife.get(currentPlayer.getId()))
                    .append(" life")
                    .toString());
            firstInactivePlayer = null;
          }
        }

        // get next player
        playerList.getNext();
        currentPlayer = game.getPlayer(playerList.get());

        // if all player since this player didn't put permanent in play finish the process
        if (currentPlayer.getId().equals(firstInactivePlayer)) {
          break;
        }
      }

      // create tokens according to life spent by each player
      RatToken token = new RatToken();
      for (Map.Entry<UUID, Integer> entry : payLife.entrySet()) {
        Player player = game.getPlayer(entry.getKey());
        if (player != null) {
          token.putOntoBattlefield(entry.getValue(), game, source.getSourceId(), player.getId());
        }
      }
    }
    return true;
  }
예제 #6
0
 private void multiBlockerDamage(boolean first, Game game) {
   // TODO:  handle banding
   Permanent attacker = game.getPermanent(attackers.get(0));
   if (attacker == null) {
     return;
   }
   Player player = game.getPlayer(attacker.getControllerId());
   int damage = getDamageValueFromPermanent(attacker, game);
   if (canDamage(attacker, first)) {
     // must be set before attacker damage marking because of effects like Test of Faith
     Map<UUID, Integer> blockerPower = new HashMap<>();
     for (UUID blockerId : blockerOrder) {
       Permanent blocker = game.getPermanent(blockerId);
       if (canDamage(blocker, first)) {
         if (blocker.getBlocking() == 1) { // blocking several creatures handled separately
           blockerPower.put(blockerId, getDamageValueFromPermanent(blocker, game));
         }
       }
     }
     Map<UUID, Integer> assigned = new HashMap<>();
     if (blocked) {
       for (UUID blockerId : blockerOrder) {
         Permanent blocker = game.getPermanent(blockerId);
         int lethalDamage;
         if (attacker.getAbilities().containsKey(DeathtouchAbility.getInstance().getId())) {
           lethalDamage = 1;
         } else {
           lethalDamage = blocker.getToughness().getValue() - blocker.getDamage();
         }
         if (lethalDamage >= damage) {
           assigned.put(blockerId, damage);
           damage = 0;
           break;
         }
         int damageAssigned =
             player.getAmount(
                 lethalDamage, damage, "Assign damage to " + blocker.getLogName(), game);
         assigned.put(blockerId, damageAssigned);
         damage -= damageAssigned;
       }
       if (damage > 0 && hasTrample(attacker)) {
         defenderDamage(attacker, damage, game);
       }
     }
     for (UUID blockerId : blockerOrder) {
       Integer power = blockerPower.get(blockerId);
       if (power != null) {
         attacker.markDamage(power.intValue(), blockerId, game, true, true);
       }
     }
     for (Map.Entry<UUID, Integer> entry : assigned.entrySet()) {
       Permanent blocker = game.getPermanent(entry.getKey());
       blocker.markDamage(entry.getValue(), attacker.getId(), game, true, true);
     }
   } else {
     for (UUID blockerId : blockerOrder) {
       Permanent blocker = game.getPermanent(blockerId);
       if (canDamage(blocker, first)) {
         attacker.markDamage(
             getDamageValueFromPermanent(blocker, game), blocker.getId(), game, true, true);
       }
     }
   }
 }