Example #1
0
 public void addBlocker(UUID blockerId, UUID playerId, Game game) {
   for (UUID attackerId : attackers) {
     if (game.replaceEvent(
         GameEvent.getEvent(
             GameEvent.EventType.DECLARE_BLOCKER, attackerId, blockerId, playerId))) {
       return;
     }
   }
   Permanent blocker = game.getPermanent(blockerId);
   if (blockerId != null && blocker != null) {
     blocker.setBlocking(blocker.getBlocking() + 1);
     blockers.add(blockerId);
     blockerOrder.add(blockerId);
     this.blocked = true;
     this.players.put(blockerId, playerId);
   }
 }
Example #2
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);
       }
     }
   }
 }
Example #3
0
  public boolean checkBlockRestrictions(Game game, int blockersCount) {
    boolean blockWasLegal = true;
    if (attackers.isEmpty()) {
      return blockWasLegal;
    }
    if (blockersCount == 1) {
      List<UUID> toBeRemoved = new ArrayList<>();
      for (UUID blockerId : getBlockers()) {
        Permanent blocker = game.getPermanent(blockerId);
        if (blocker != null
            && blocker.getAbilities().containsKey(CantBlockAloneAbility.getInstance().getId())) {
          blockWasLegal = false;
          game.informPlayers(blocker.getLogName() + " can't block alone. Removing it from combat.");
          toBeRemoved.add(blockerId);
        }
      }

      for (UUID blockerId : toBeRemoved) {
        game.getCombat().removeBlocker(blockerId, game);
      }
      if (blockers.isEmpty()) {
        this.blocked = false;
      }
    }

    for (UUID uuid : attackers) {
      Permanent attacker = game.getPermanent(uuid);
      // Check if there are enough blockers to have a legal block
      if (attacker != null
          && this.blocked
          && attacker.getMinBlockedBy() > 1
          && blockers.size() > 0
          && blockers.size() < attacker.getMinBlockedBy()) {
        for (UUID blockerId : blockers) {
          Permanent blocker = game.getPermanent(blockerId);
          if (blocker != null) {
            blocker.setBlocking(blocker.getBlocking() - 1);
          }
        }
        blockers.clear();
        blockerOrder.clear();
        this.blocked = false;
        game.informPlayers(
            attacker.getLogName()
                + " can't be blocked except by "
                + attacker.getMinBlockedBy()
                + " or more creatures. Blockers discarded.");
        blockWasLegal = false;
      }
      // Check if there are to many blockers (maxBlockedBy = 0 means no restrictions)
      if (attacker != null
          && this.blocked
          && attacker.getMaxBlockedBy() > 0
          && attacker.getMaxBlockedBy() < blockers.size()) {
        for (UUID blockerId : blockers) {
          Permanent blocker = game.getPermanent(blockerId);
          if (blocker != null) {
            blocker.setBlocking(blocker.getBlocking() - 1);
          }
        }
        blockers.clear();
        blockerOrder.clear();
        this.blocked = false;
        game.informPlayers(
            new StringBuilder(attacker.getLogName())
                .append(" can't be blocked by more than ")
                .append(attacker.getMaxBlockedBy())
                .append(attacker.getMaxBlockedBy() == 1 ? " creature." : " creatures.")
                .append(" Blockers discarded.")
                .toString());
        blockWasLegal = false;
      }
    }
    return blockWasLegal;
  }
Example #4
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);
       }
     }
   }
 }