예제 #1
0
 @Override
 public boolean replaceEvent(GameEvent event, Ability source, Game game) {
   PreventionEffectData preventionResult = preventDamageAction(event, source, game);
   if (preventionResult.getPreventedDamage() > 0) {
     Permanent redirectTo = game.getPermanent(getTargetPointer().getFirst(game, source));
     if (redirectTo != null) {
       game.informPlayers(
           "Dealing "
               + preventionResult.getPreventedDamage()
               + " to "
               + redirectTo.getLogName()
               + " instead.");
       DamageEvent damageEvent = (DamageEvent) event;
       redirectTo.damage(
           preventionResult.getPreventedDamage(),
           event.getSourceId(),
           game,
           damageEvent.isCombatDamage(),
           damageEvent.isPreventable(),
           event.getAppliedEffects());
     }
     discard(); // (only once)
   }
   return false;
 }
예제 #2
0
 @Override
 public boolean replaceEvent(GameEvent event, Ability source, Game game) {
   DamageEvent damageEvent = (DamageEvent) event;
   Permanent sourcePermanent = game.getPermanent(source.getSourceId());
   if (sourcePermanent != null) {
     // get name of old target
     Permanent targetPermanent = game.getPermanent(event.getTargetId());
     StringBuilder message = new StringBuilder();
     message.append(sourcePermanent.getName()).append(": gets ");
     message.append(damageEvent.getAmount()).append(" damage redirected from ");
     if (targetPermanent != null) {
       message.append(targetPermanent.getName());
     } else {
       Player targetPlayer = game.getPlayer(event.getTargetId());
       if (targetPlayer != null) {
         message.append(targetPlayer.getName());
       } else {
         message.append("unknown");
       }
     }
     game.informPlayers(message.toString());
     // redirect damage
     this.used = true;
     sourcePermanent.damage(
         damageEvent.getAmount(),
         damageEvent.getSourceId(),
         game,
         damageEvent.isPreventable(),
         damageEvent.isCombatDamage(),
         event.getAppliedEffects());
     return true;
   }
   return false;
 }
예제 #3
0
  public boolean replaceEvent(GameEvent event, Game game) {
    boolean caught = false;
    HashMap<UUID, HashSet<UUID>> consumed = new HashMap<>();
    do {
      HashMap<ReplacementEffect, HashSet<Ability>> rEffects =
          getApplicableReplacementEffects(event, game);
      // Remove all consumed effects (ability dependant)
      for (Iterator<ReplacementEffect> it1 = rEffects.keySet().iterator(); it1.hasNext(); ) {
        ReplacementEffect entry = it1.next();
        if (consumed.containsKey(entry.getId())) {
          HashSet<UUID> consumedAbilitiesIds = consumed.get(entry.getId());
          if (rEffects.get(entry) == null
              || consumedAbilitiesIds.size() == rEffects.get(entry).size()) {
            it1.remove();
          } else {
            Iterator it = rEffects.get(entry).iterator();
            while (it.hasNext()) {
              Ability ability = (Ability) it.next();
              if (consumedAbilitiesIds.contains(ability.getId())) {
                it.remove();
              }
            }
          }
        }
      }
      // no effects left, quit
      if (rEffects.isEmpty()) {
        break;
      }
      int index;
      boolean onlyOne = false;
      if (rEffects.size() == 1) {
        ReplacementEffect effect = rEffects.keySet().iterator().next();
        HashSet<Ability> abilities;
        if (effect.getEffectType().equals(EffectType.REPLACEMENT)) {
          abilities = replacementEffects.getAbility(effect.getId());
        } else {
          abilities = preventionEffects.getAbility(effect.getId());
        }
        if (abilities == null || abilities.size() == 1) {
          onlyOne = true;
        }
      }
      if (onlyOne) {
        index = 0;
      } else {
        // 20100716 - 616.1c
        Player player = game.getPlayer(event.getPlayerId());
        index = player.chooseReplacementEffect(getReplacementEffectsTexts(rEffects, game), game);
      }
      // get the selected effect
      int checked = 0;
      ReplacementEffect rEffect = null;
      Ability rAbility = null;
      for (Map.Entry<ReplacementEffect, HashSet<Ability>> entry : rEffects.entrySet()) {
        if (entry.getValue() == null) {
          if (checked == index) {
            rEffect = entry.getKey();
            break;
          } else {
            checked++;
          }
        } else {
          HashSet<Ability> abilities = entry.getValue();
          int size = abilities.size();
          if (index > (checked + size - 1)) {
            checked += size;
          } else {
            rEffect = entry.getKey();
            Iterator it = abilities.iterator();
            while (it.hasNext() && rAbility == null) {
              if (checked == index) {
                rAbility = (Ability) it.next();
              } else {
                it.next();
                checked++;
              }
            }
            break;
          }
        }
      }

      if (rEffect != null) {
        event.getAppliedEffects().add(rEffect.getId());
        caught = rEffect.replaceEvent(event, rAbility, game);
      }
      if (caught) { // Event was completely replaced -> stop applying effects to it
        break;
      }

      // add the applied effect to the consumed effects
      if (rEffect != null) {
        if (consumed.containsKey(rEffect.getId())) {
          HashSet<UUID> set = consumed.get(rEffect.getId());
          if (rAbility != null) {
            if (!set.contains(rAbility.getId())) {
              set.add(rAbility.getId());
            }
          }
        } else {
          HashSet<UUID> set = new HashSet<>();
          if (rAbility
              != null) { // in case of AuraReplacementEffect or PlaneswalkerReplacementEffect there
                         // is no Ability
            set.add(rAbility.getId());
          }
          consumed.put(rEffect.getId(), set);
        }
      }
      // Must be called here for some effects to be able to work correctly
      // TODO: add info which effects need that call
      game.applyEffects();
    } while (true);
    return caught;
  }
예제 #4
0
 /**
  * @param event
  * @param game
  * @return a list of all {@link ReplacementEffect} that apply to the current event
  */
 private HashMap<ReplacementEffect, HashSet<Ability>> getApplicableReplacementEffects(
     GameEvent event, Game game) {
   HashMap<ReplacementEffect, HashSet<Ability>> replaceEffects = new HashMap<>();
   if (planeswalkerRedirectionEffect.checksEventType(event, game)
       && planeswalkerRedirectionEffect.applies(event, null, game)) {
     replaceEffects.put(planeswalkerRedirectionEffect, null);
   }
   if (auraReplacementEffect.checksEventType(event, game)
       && auraReplacementEffect.applies(event, null, game)) {
     replaceEffects.put(auraReplacementEffect, null);
   }
   // boolean checkLKI = event.getType().equals(EventType.ZONE_CHANGE) ||
   // event.getType().equals(EventType.DESTROYED_PERMANENT);
   // get all applicable transient Replacement effects
   for (ReplacementEffect effect : replacementEffects) {
     if (!effect.checksEventType(event, game)) {
       continue;
     }
     if (event.getAppliedEffects() != null && event.getAppliedEffects().contains(effect.getId())) {
       // Effect already applied to this event, ignore it
       // TODO: Handle also gained effect that are connected to different abilities.
       continue;
     }
     HashSet<Ability> abilities = replacementEffects.getAbility(effect.getId());
     HashSet<Ability> applicableAbilities = new HashSet<>();
     for (Ability ability : abilities) {
       // for replacment effects of static abilities do not use LKI to check if to apply
       if (ability.getAbilityType() != AbilityType.STATIC
           || ability.isInUseableZone(game, null, event)) {
         if (effect.getDuration() != Duration.OneUse || !effect.isUsed()) {
           if (!game.getScopeRelevant()
               || effect.hasSelfScope()
               || !event.getTargetId().equals(ability.getSourceId())) {
             if (effect.applies(event, ability, game)) {
               applicableAbilities.add(ability);
             }
           }
         }
       }
     }
     if (!applicableAbilities.isEmpty()) {
       replaceEffects.put(effect, applicableAbilities);
     }
   }
   for (PreventionEffect effect : preventionEffects) {
     if (!effect.checksEventType(event, game)) {
       continue;
     }
     if (event.getAppliedEffects() != null && event.getAppliedEffects().contains(effect.getId())) {
       // Effect already applied to this event, ignore it
       // TODO: Handle also gained effect that are connected to different abilities.
       continue;
     }
     HashSet<Ability> abilities = preventionEffects.getAbility(effect.getId());
     HashSet<Ability> applicableAbilities = new HashSet<>();
     for (Ability ability : abilities) {
       if (ability.getAbilityType() != AbilityType.STATIC
           || ability.isInUseableZone(game, null, event)) {
         if (effect.getDuration() != Duration.OneUse || !effect.isUsed()) {
           if (effect.applies(event, ability, game)) {
             applicableAbilities.add(ability);
           }
         }
       }
     }
     if (!applicableAbilities.isEmpty()) {
       replaceEffects.put((ReplacementEffect) effect, applicableAbilities);
     }
   }
   return replaceEffects;
 }