Beispiel #1
0
 public UUID getControllerOfSourceId(UUID sourceId) {
   UUID controllerFound = null;
   for (PreventionEffect effect : preventionEffects) {
     HashSet<Ability> abilities = preventionEffects.getAbility(effect.getId());
     for (Ability ability : abilities) {
       if (ability.getSourceId().equals(sourceId)) {
         if (controllerFound == null || controllerFound == ability.getControllerId()) {
           controllerFound = ability.getControllerId();
         } else {
           // not unique controller - No solution yet
           return null;
         }
       }
     }
   }
   for (ReplacementEffect effect : replacementEffects) {
     HashSet<Ability> abilities = replacementEffects.getAbility(effect.getId());
     for (Ability ability : abilities) {
       if (ability.getSourceId().equals(sourceId)) {
         if (controllerFound == null || controllerFound == ability.getControllerId()) {
           controllerFound = ability.getControllerId();
         } else {
           // not unique controller - No solution yet
           return null;
         }
       }
     }
   }
   return controllerFound;
 }
Beispiel #2
0
 public void addEffect(ContinuousEffect effect, Ability source) {
   if (effect == null) {
     logger.error("Effect is null: " + source.toString());
     return;
   } else if (source == null) {
     logger.warn("Adding effect without ability : " + effect.toString());
   }
   switch (effect.getEffectType()) {
     case REPLACEMENT:
     case REDIRECTION:
       ReplacementEffect newReplacementEffect = (ReplacementEffect) effect;
       replacementEffects.addEffect(newReplacementEffect, source);
       break;
     case PREVENTION:
       PreventionEffect newPreventionEffect = (PreventionEffect) effect;
       preventionEffects.addEffect(newPreventionEffect, source);
       break;
     case RESTRICTION:
       RestrictionEffect newRestrictionEffect = (RestrictionEffect) effect;
       restrictionEffects.addEffect(newRestrictionEffect, source);
       break;
     case RESTRICTION_UNTAP_NOT_MORE_THAN:
       RestrictionUntapNotMoreThanEffect newRestrictionUntapNotMoreThanEffect =
           (RestrictionUntapNotMoreThanEffect) effect;
       restrictionUntapNotMoreThanEffects.addEffect(newRestrictionUntapNotMoreThanEffect, source);
       break;
     case REQUIREMENT:
       RequirementEffect newRequirementEffect = (RequirementEffect) effect;
       requirementEffects.addEffect(newRequirementEffect, source);
       break;
     case ASTHOUGH:
       AsThoughEffect newAsThoughEffect = (AsThoughEffect) effect;
       if (!asThoughEffectsMap.containsKey(newAsThoughEffect.getAsThoughEffectType())) {
         ContinuousEffectsList<AsThoughEffect> list = new ContinuousEffectsList<>();
         allEffectsLists.add(list);
         asThoughEffectsMap.put(newAsThoughEffect.getAsThoughEffectType(), list);
       }
       asThoughEffectsMap
           .get(newAsThoughEffect.getAsThoughEffectType())
           .addEffect(newAsThoughEffect, source);
       break;
     case COSTMODIFICATION:
       CostModificationEffect newCostModificationEffect = (CostModificationEffect) effect;
       costModificationEffects.addEffect(newCostModificationEffect, source);
       break;
     case SPLICE:
       SpliceCardEffect newSpliceCardEffect = (SpliceCardEffect) effect;
       spliceCardEffects.addEffect(newSpliceCardEffect, source);
       break;
     case CONTINUOUS_RULE_MODIFICATION:
       ContinuousRuleModifyingEffect newContinuousRuleModifiyingEffect =
           (ContinuousRuleModifyingEffect) effect;
       continuousRuleModifyingEffects.addEffect(newContinuousRuleModifiyingEffect, source);
       break;
     default:
       layeredEffects.addEffect(effect, source);
       break;
   }
 }
Beispiel #3
0
 public void removeEndOfTurnEffects() {
   layeredEffects.removeEndOfTurnEffects();
   continuousRuleModifyingEffects.removeEndOfTurnEffects();
   replacementEffects.removeEndOfTurnEffects();
   preventionEffects.removeEndOfTurnEffects();
   requirementEffects.removeEndOfTurnEffects();
   restrictionEffects.removeEndOfTurnEffects();
   for (ContinuousEffectsList asThoughtlist : asThoughEffectsMap.values()) {
     asThoughtlist.removeEndOfTurnEffects();
   }
   costModificationEffects.removeEndOfTurnEffects();
   spliceCardEffects.removeEndOfTurnEffects();
 }
Beispiel #4
0
  public List<ContinuousEffect> getLayeredEffects(Game game) {
    List<ContinuousEffect> layerEffects = new ArrayList<>();
    for (ContinuousEffect effect : layeredEffects) {
      switch (effect.getDuration()) {
        case WhileOnBattlefield:
        case WhileOnStack:
        case WhileInGraveyard:
          HashSet<Ability> abilities = layeredEffects.getAbility(effect.getId());
          for (Ability ability : abilities) {
            // If e.g. triggerd abilities (non static) created the effect, the ability must not be
            // in usable zone (e.g. Unearth giving Haste effect)
            if (!(ability instanceof StaticAbility) || ability.isInUseableZone(game, null, null)) {
              layerEffects.add(effect);
              break;
            }
          }
          break;
        default:
          layerEffects.add(effect);
      }
    }

    updateTimestamps(layerEffects);

    Collections.sort(layerEffects, sorter);
    return layerEffects;
  }
Beispiel #5
0
  /**
   * Checks all available splice effects to be applied.
   *
   * @param abilityToModify
   * @param game
   */
  public void applySpliceEffects(Ability abilityToModify, Game game) {
    if (((SpellAbility) abilityToModify).getSpellAbilityType().equals(SpellAbilityType.SPLICE)) {
      // on a spliced ability of a spell can't be spliced again
      return;
    }
    List<SpliceCardEffect> spliceEffects =
        getApplicableSpliceCardEffects(game, abilityToModify.getControllerId());
    // get the applyable splice abilities
    List<SpliceOntoArcaneAbility> spliceAbilities = new ArrayList<>();
    for (SpliceCardEffect effect : spliceEffects) {
      HashSet<Ability> abilities = spliceCardEffects.getAbility(effect.getId());
      for (Ability ability : abilities) {
        if (effect.applies(abilityToModify, ability, game)) {
          spliceAbilities.add((SpliceOntoArcaneAbility) ability);
        }
      }
    }
    // check if player wants to use splice

    if (spliceAbilities.size() > 0) {
      Player controller = game.getPlayer(abilityToModify.getControllerId());
      if (controller.chooseUse(Outcome.Benefit, "Splice a card?", game)) {
        Cards cardsToReveal = new CardsImpl();
        do {
          FilterCard filter = new FilterCard("a card to splice");
          ArrayList<Predicate<MageObject>> idPredicates = new ArrayList<>();
          for (SpliceOntoArcaneAbility ability : spliceAbilities) {
            idPredicates.add(new CardIdPredicate((ability.getSourceId())));
          }
          filter.add(Predicates.or(idPredicates));
          TargetCardInHand target = new TargetCardInHand(filter);
          controller.chooseTarget(Outcome.Benefit, target, abilityToModify, game);
          UUID cardId = target.getFirstTarget();
          if (cardId != null) {
            SpliceOntoArcaneAbility selectedAbility = null;
            for (SpliceOntoArcaneAbility ability : spliceAbilities) {
              if (ability.getSourceId().equals(cardId)) {
                selectedAbility = ability;
                break;
              }
            }
            if (selectedAbility != null) {
              SpliceCardEffect spliceEffect =
                  (SpliceCardEffect) selectedAbility.getEffects().get(0);
              spliceEffect.apply(game, selectedAbility, abilityToModify);
              cardsToReveal.add(game.getCard(cardId));
              spliceAbilities.remove(selectedAbility);
            }
          }
        } while (!spliceAbilities.isEmpty()
            && controller.chooseUse(Outcome.Benefit, "Splice another card?", game));
        controller.revealCards("Spliced cards", cardsToReveal, game);
      }
    }
  }
Beispiel #6
0
 public void removeAllTemporaryEffects() {
   for (Map.Entry<ContinuousEffect, Set<Ability>> entry : temporaryEffects.entrySet()) {
     switch (entry.getKey().getEffectType()) {
       case REPLACEMENT:
       case REDIRECTION:
         replacementEffects.removeEffects(entry.getKey().getId(), entry.getValue());
         break;
       case PREVENTION:
         preventionEffects.removeEffects(entry.getKey().getId(), entry.getValue());
         break;
       case RESTRICTION:
         restrictionEffects.removeEffects(entry.getKey().getId(), entry.getValue());
         break;
       case RESTRICTION_UNTAP_NOT_MORE_THAN:
         restrictionUntapNotMoreThanEffects.removeEffects(
             entry.getKey().getId(), entry.getValue());
         break;
       case REQUIREMENT:
         requirementEffects.removeEffects(entry.getKey().getId(), entry.getValue());
         break;
       case ASTHOUGH:
         AsThoughEffect newAsThoughEffect = (AsThoughEffect) entry.getKey();
         if (!asThoughEffectsMap.containsKey(newAsThoughEffect.getAsThoughEffectType())) {
           break;
         }
         asThoughEffectsMap
             .get(newAsThoughEffect.getAsThoughEffectType())
             .removeEffects(entry.getKey().getId(), entry.getValue());
         break;
       case COSTMODIFICATION:
         costModificationEffects.removeEffects(entry.getKey().getId(), entry.getValue());
         break;
       case SPLICE:
         spliceCardEffects.removeEffects(entry.getKey().getId(), entry.getValue());
         break;
       case CONTINUOUS_RULE_MODIFICATION:
         continuousRuleModifyingEffects.removeEffects(entry.getKey().getId(), entry.getValue());
         break;
       default:
         layeredEffects.removeEffects(entry.getKey().getId(), entry.getValue());
         break;
     }
   }
   temporaryEffects.clear();
 }
Beispiel #7
0
  /**
   * Inspects all {@link Permanent permanent's} {@link Ability abilities} on the battlefield for
   * {@link CostModificationEffect cost modification effects} and applies them if necessary.
   *
   * @param abilityToModify
   * @param game
   */
  public void costModification(Ability abilityToModify, Game game) {
    List<CostModificationEffect> costEffects = getApplicableCostModificationEffects(game);

    for (CostModificationEffect effect : costEffects) {
      if (effect.getModificationType() == CostModificationType.INCREASE_COST) {
        HashSet<Ability> abilities = costModificationEffects.getAbility(effect.getId());
        for (Ability ability : abilities) {
          if (effect.applies(abilityToModify, ability, game)) {
            effect.apply(game, ability, abilityToModify);
          }
        }
      }
    }

    for (CostModificationEffect effect : costEffects) {
      if (effect.getModificationType() == CostModificationType.REDUCE_COST) {
        HashSet<Ability> abilities = costModificationEffects.getAbility(effect.getId());
        for (Ability ability : abilities) {
          if (effect.applies(abilityToModify, ability, game)) {
            effect.apply(game, ability, abilityToModify);
          }
        }
      }
    }

    for (CostModificationEffect effect : costEffects) {
      if (effect.getModificationType() == CostModificationType.SET_COST) {
        HashSet<Ability> abilities = costModificationEffects.getAbility(effect.getId());
        for (Ability ability : abilities) {
          if (effect.applies(abilityToModify, ability, game)) {
            effect.apply(game, ability, abilityToModify);
          }
        }
      }
    }
  }
Beispiel #8
0
 private void setControllerForEffect(
     ContinuousEffectsList<?> effects, UUID cardId, UUID controllerId) {
   for (Effect effect : effects) {
     HashSet<Ability> abilities = effects.getAbility(effect.getId());
     for (Ability ability : abilities) {
       if (ability.getSourceId() != null) {
         if (ability.getSourceId().equals(cardId)) {
           ability.setControllerId(controllerId);
         }
       } else {
         if (!ability.getZone().equals(Zone.COMMAND)) {
           logger.fatal(new StringBuilder("No sourceId Ability: ").append(ability));
         }
       }
     }
   }
 }
Beispiel #9
0
  /**
   * Filters out cost modification effects that are not active.
   *
   * @param game
   * @return
   */
  private List<CostModificationEffect> getApplicableCostModificationEffects(Game game) {
    List<CostModificationEffect> costEffects = new ArrayList<>();

    for (CostModificationEffect effect : costModificationEffects) {
      HashSet<Ability> abilities = costModificationEffects.getAbility(effect.getId());
      for (Ability ability : abilities) {
        if (!(ability instanceof StaticAbility) || ability.isInUseableZone(game, null, null)) {
          if (effect.getDuration() != Duration.OneUse || !effect.isUsed()) {
            costEffects.add(effect);
            break;
          }
        }
      }
    }

    return costEffects;
  }
Beispiel #10
0
  /**
   * Filters out splice effects that are not active.
   *
   * @param game
   * @return
   */
  private List<SpliceCardEffect> getApplicableSpliceCardEffects(Game game, UUID playerId) {
    List<SpliceCardEffect> spliceEffects = new ArrayList<>();

    for (SpliceCardEffect effect : spliceCardEffects) {
      HashSet<Ability> abilities = spliceCardEffects.getAbility(effect.getId());
      for (Ability ability : abilities) {
        if (ability.getControllerId().equals(playerId)
            && (!(ability instanceof StaticAbility) || ability.isInUseableZone(game, null, null))) {
          if (effect.getDuration() != Duration.OneUse || !effect.isUsed()) {
            spliceEffects.add(effect);
            break;
          }
        }
      }
    }

    return spliceEffects;
  }
Beispiel #11
0
 public HashMap<RestrictionUntapNotMoreThanEffect, HashSet<Ability>>
     getApplicableRestrictionUntapNotMoreThanEffects(Player player, Game game) {
   HashMap<RestrictionUntapNotMoreThanEffect, HashSet<Ability>> effects = new HashMap<>();
   for (RestrictionUntapNotMoreThanEffect effect : restrictionUntapNotMoreThanEffects) {
     HashSet<Ability> abilities = restrictionUntapNotMoreThanEffects.getAbility(effect.getId());
     HashSet<Ability> applicableAbilities = new HashSet<>();
     for (Ability ability : abilities) {
       if (!(ability instanceof StaticAbility) || ability.isInUseableZone(game, null, null)) {
         if (effect.applies(player, ability, game)) {
           applicableAbilities.add(ability);
         }
       }
     }
     if (!applicableAbilities.isEmpty()) {
       effects.put(effect, abilities);
     }
   }
   return effects;
 }
Beispiel #12
0
 public HashMap<RestrictionEffect, HashSet<Ability>> getApplicableRestrictionEffects(
     Permanent permanent, Game game) {
   HashMap<RestrictionEffect, HashSet<Ability>> effects = new HashMap<>();
   for (RestrictionEffect effect : restrictionEffects) {
     HashSet<Ability> abilities = restrictionEffects.getAbility(effect.getId());
     HashSet<Ability> applicableAbilities = new HashSet<>();
     for (Ability ability : abilities) {
       if (!(ability instanceof StaticAbility)
           || ability.isInUseableZone(
               game, ability instanceof MageSingleton ? permanent : null, null)) {
         if (effect.applies(permanent, ability, game)) {
           applicableAbilities.add(ability);
         }
       }
     }
     if (!applicableAbilities.isEmpty()) {
       effects.put(effect, abilities);
     }
   }
   return effects;
 }
Beispiel #13
0
 /**
  * Checks if an event won't happen because of an rule modifying effect
  *
  * @param event
  * @param targetAbility ability the event is attached to. can be null.
  * @param game
  * @param checkPlayableMode true if the event does not really happen but it's checked if the event
  *     would be replaced
  * @return
  */
 public boolean preventedByRuleModification(
     GameEvent event, Ability targetAbility, Game game, boolean checkPlayableMode) {
   for (ContinuousRuleModifyingEffect effect : continuousRuleModifyingEffects) {
     if (!effect.checksEventType(event, game)) {
       continue;
     }
     for (Ability sourceAbility : continuousRuleModifyingEffects.getAbility(effect.getId())) {
       if (!(sourceAbility instanceof StaticAbility)
           || sourceAbility.isInUseableZone(game, null, event)) {
         if (checkAbilityStillExists(sourceAbility, effect, event, game)) {
           if (effect.getDuration() != Duration.OneUse || !effect.isUsed()) {
             effect.setValue("targetAbility", targetAbility);
             if (effect.applies(event, sourceAbility, game)) {
               if (!checkPlayableMode) {
                 String message = effect.getInfoMessage(sourceAbility, event, game);
                 if (message != null && !message.isEmpty()) {
                   if (effect.sendMessageToUser()) {
                     Player player = game.getPlayer(event.getPlayerId());
                     if (player != null && !game.isSimulation()) {
                       game.informPlayer(player, message);
                     }
                   }
                   if (effect.sendMessageToGameLog() && !game.isSimulation()) {
                     game.informPlayers(message);
                   }
                 }
               }
               return true;
             }
           }
         }
       }
     }
   }
   return false;
 }
Beispiel #14
0
  // 20091005 - 613
  public void apply(Game game) {
    removeInactiveEffects(game);
    List<ContinuousEffect> layerEffects = getLayeredEffects(game);
    List<ContinuousEffect> layer = filterLayeredEffects(layerEffects, Layer.CopyEffects_1);
    for (ContinuousEffect effect : layer) {
      HashSet<Ability> abilities = layeredEffects.getAbility(effect.getId());
      for (Ability ability : abilities) {
        effect.apply(Layer.CopyEffects_1, SubLayer.NA, ability, game);
      }
    }
    // Reload layerEffect if copy effects were applied
    if (layer.size() > 0) {
      layerEffects = getLayeredEffects(game);
    }

    layer = filterLayeredEffects(layerEffects, Layer.ControlChangingEffects_2);
    // apply control changing effects multiple times if it's needed
    // for cases when control over permanents with change control abilities is changed
    // e.g. Mind Control is controlled by Steal Enchantment
    while (true) {
      for (ContinuousEffect effect : layer) {
        HashSet<Ability> abilities = layeredEffects.getAbility(effect.getId());
        for (Ability ability : abilities) {
          effect.apply(Layer.ControlChangingEffects_2, SubLayer.NA, ability, game);
        }
      }
      // if control over all permanent has not changed, we can no longer reapply control changing
      // effects
      if (!game.getBattlefield().fireControlChangeEvents(game)) {
        break;
      }
      // reset control before reapplying control changing effects
      game.getBattlefield().resetPermanentsControl();
    }
    layer = filterLayeredEffects(layerEffects, Layer.TextChangingEffects_3);
    for (ContinuousEffect effect : layer) {
      HashSet<Ability> abilities = layeredEffects.getAbility(effect.getId());
      for (Ability ability : abilities) {
        effect.apply(Layer.TextChangingEffects_3, SubLayer.NA, ability, game);
      }
    }
    layer = filterLayeredEffects(layerEffects, Layer.TypeChangingEffects_4);
    for (ContinuousEffect effect : layer) {
      HashSet<Ability> abilities = layeredEffects.getAbility(effect.getId());
      for (Ability ability : abilities) {
        effect.apply(Layer.TypeChangingEffects_4, SubLayer.NA, ability, game);
      }
    }
    layer = filterLayeredEffects(layerEffects, Layer.ColorChangingEffects_5);
    for (ContinuousEffect effect : layer) {
      HashSet<Ability> abilities = layeredEffects.getAbility(effect.getId());
      for (Ability ability : abilities) {
        effect.apply(Layer.ColorChangingEffects_5, SubLayer.NA, ability, game);
      }
    }

    Map<ContinuousEffect, List<Ability>> appliedEffects = new HashMap<>();
    boolean done = false;
    while (!done) { // loop needed if a added effect adds again an effect (e.g. Level 5- of Joraga
                    // Treespeaker)
      done = true;
      layer = filterLayeredEffects(layerEffects, Layer.AbilityAddingRemovingEffects_6);
      for (ContinuousEffect effect : layer) {
        if (layerEffects.contains(effect)) {
          List<Ability> appliedAbilities = appliedEffects.get(effect);
          HashSet<Ability> abilities = layeredEffects.getAbility(effect.getId());
          for (Ability ability : abilities) {
            if (appliedAbilities == null || !appliedAbilities.contains(ability)) {
              if (appliedAbilities == null) {
                appliedAbilities = new ArrayList<>();
                appliedEffects.put(effect, appliedAbilities);
              }
              appliedAbilities.add(ability);
              effect.apply(Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, ability, game);
              done = false;
              // list must be updated after each applied effect (eg. if "Turn to Frog" removes
              // abilities)
              layerEffects = getLayeredEffects(game);
            }
          }
        }
      }
    }

    layer = filterLayeredEffects(layerEffects, Layer.PTChangingEffects_7);
    for (ContinuousEffect effect : layer) {
      HashSet<Ability> abilities = layeredEffects.getAbility(effect.getId());
      for (Ability ability : abilities) {
        effect.apply(Layer.PTChangingEffects_7, SubLayer.SetPT_7b, ability, game);
      }
    }
    for (ContinuousEffect effect : layer) {
      HashSet<Ability> abilities = layeredEffects.getAbility(effect.getId());
      for (Ability ability : abilities) {
        effect.apply(Layer.PTChangingEffects_7, SubLayer.ModifyPT_7c, ability, game);
      }
    }

    applyCounters.apply(Layer.PTChangingEffects_7, SubLayer.Counters_7d, null, game);

    for (ContinuousEffect effect : layer) {
      HashSet<Ability> abilities = layeredEffects.getAbility(effect.getId());
      for (Ability ability : abilities) {
        effect.apply(Layer.PTChangingEffects_7, SubLayer.SwitchPT_e, ability, game);
      }
    }
    layer = filterLayeredEffects(layerEffects, Layer.PlayerEffects);
    for (ContinuousEffect effect : layer) {
      HashSet<Ability> abilities = layeredEffects.getAbility(effect.getId());
      for (Ability ability : abilities) {
        effect.apply(Layer.PlayerEffects, SubLayer.NA, ability, game);
      }
    }
    layer = filterLayeredEffects(layerEffects, Layer.RulesEffects);
    for (ContinuousEffect effect : layer) {
      HashSet<Ability> abilities = layeredEffects.getAbility(effect.getId());
      for (Ability ability : abilities) {
        effect.apply(Layer.RulesEffects, SubLayer.NA, ability, game);
      }
    }
  }
Beispiel #15
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;
  }
Beispiel #16
0
 public void clear() {
   for (ContinuousEffectsList effectsList : allEffectsLists) {
     effectsList.clear();
   }
   temporaryEffects.clear();
 }
Beispiel #17
0
 public boolean existRequirementEffects() {
   return !requirementEffects.isEmpty();
 }
Beispiel #18
0
 public void removeInactiveEffects(Game game) {
   layeredEffects.removeInactiveEffects(game);
   continuousRuleModifyingEffects.removeInactiveEffects(game);
   replacementEffects.removeInactiveEffects(game);
   preventionEffects.removeInactiveEffects(game);
   requirementEffects.removeInactiveEffects(game);
   restrictionEffects.removeInactiveEffects(game);
   restrictionUntapNotMoreThanEffects.removeInactiveEffects(game);
   for (ContinuousEffectsList asThoughtlist : asThoughEffectsMap.values()) {
     asThoughtlist.removeInactiveEffects(game);
   }
   costModificationEffects.removeInactiveEffects(game);
   spliceCardEffects.removeInactiveEffects(game);
 }
Beispiel #19
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;
 }