public Set<Ability> getLayeredEffectAbilities(ContinuousEffect effect) { return layeredEffects.getAbility(effect.getId()); }
@Override public Set<UUID> isDependentTo(List<ContinuousEffect> allEffectsInLayer) { Set<UUID> dependentTo = new HashSet<>(); for (ContinuousEffect effect : allEffectsInLayer) { for (DependencyType dependencyType : effect.getDependencyTypes()) { if (checkDependencyTypes.contains(dependencyType)) { dependentTo.add(effect.getId()); } } } return dependentTo; } }
public void removeInactiveEffects(Game game) { for (Iterator<T> i = this.iterator(); i.hasNext();) { T entry = i.next(); if (isInactive(entry, game)) { i.remove(); effectAbilityMap.remove(entry.getId()); } } }
public void removeEndOfCombatEffects() { for (Iterator<T> i = this.iterator(); i.hasNext();) { T entry = i.next(); if (entry.getDuration() == Duration.EndOfCombat) { i.remove(); effectAbilityMap.remove(entry.getId()); } } }
public void removeEffects(UUID effectIdToRemove, Set<Ability> abilitiesToRemove) { Set<Ability> abilities = effectAbilityMap.get(effectIdToRemove); if (abilitiesToRemove != null && abilities != null) { abilities.removeAll(abilitiesToRemove); } if (abilities == null || abilities.isEmpty()) { for (Iterator<T> iterator = this.iterator(); iterator.hasNext();) { ContinuousEffect effect = iterator.next(); if (effect.getId().equals(effectIdToRemove)) { iterator.remove(); break; } } effectAbilityMap.remove(effectIdToRemove); } }
public void removeEndOfTurnEffects() { for (Iterator<T> i = this.iterator(); i.hasNext();) { T entry = i.next(); if (entry.getDuration() == Duration.EndOfTurn) { i.remove(); effectAbilityMap.remove(entry.getId()); } } }
@Override public Set<UUID> isDependentTo(List<ContinuousEffect> allEffectsInLayer) { Set<UUID> dependentToEffects = new HashSet<UUID>(); if (dependendToTypes != null) { for (ContinuousEffect effect : allEffectsInLayer) { if (!effect.getId().equals(this.getId())) { for (DependencyType dependencyType : effect.getDependencyTypes()) { if (dependendToTypes.contains(dependencyType)) { dependentToEffects.add(effect.getId()); break; } } } } } return dependentToEffects; /* return allEffectsInLayer.stream() .filter(effect -> effect.getDependencyTypes().contains(dependendToTypes)) .map(Effect::getId) .collect(Collectors.toSet()); } return new HashSet<>();*/ }
private void applyLayer(List<ContinuousEffect> activeLayerEffects, Layer currentLayer, Game game) { List<ContinuousEffect> layer = filterLayeredEffects(activeLayerEffects, currentLayer); if (!layer.isEmpty()) { int numberOfEffects = layer.size(); Set<UUID> appliedEffects = new HashSet<>(); Map<ContinuousEffect, Set<UUID>> waitingEffects = new LinkedHashMap<>(); for (ContinuousEffect effect : layer) { if (numberOfEffects > 1) { // If an effect is dependent to not applied effects yet of this layer, so wait to apply this effect Set<UUID> dependentTo = effect.isDependentTo(layer); if (!appliedEffects.containsAll(dependentTo)) { waitingEffects.put(effect, dependentTo); continue; } } applyContinuousEffect(effect, currentLayer, game); appliedEffects.add(effect.getId()); if (!waitingEffects.isEmpty()) { // check if waiting effects can be applied now for (Entry<ContinuousEffect, Set<UUID>> entry : waitingEffects.entrySet()) { if (appliedEffects.containsAll(entry.getValue())) { // all dependent to effects are applied now so apply the effect itself applyContinuousEffect(entry.getKey(), currentLayer, game); appliedEffects.add(entry.getKey().getId()); } } } } } }
/** * Adds an effect and its connected ability to the list. For each effect * will be stored, which abilities are connected to the effect. So an effect * can be connected to multiple abilities. * * @param effect - effect to add * @param source - connected ability */ public void addEffect(T effect, Ability source) { if (effectAbilityMap.containsKey(effect.getId())) { Set<Ability> set = effectAbilityMap.get(effect.getId()); for (Ability ability : set) { if (ability.getId().equals(source.getId()) && ability.getSourceId().equals(source.getSourceId())) { return; } } set.add(source); return; } Set<Ability> set = new HashSet<>(); set.add(source); this.effectAbilityMap.put(effect.getId(), set); this.add(effect); }
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: 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;
public synchronized List<ContinuousEffect> getLayeredEffects(Game game) { List<ContinuousEffect> layerEffects = new ArrayList<>(); for (ContinuousEffect effect : layeredEffects) { switch (effect.getDuration()) { case WhileOnBattlefield: case WhileOnStack: case WhileInGraveyard: Set<Ability> abilities = layeredEffects.getAbility(effect.getId()); if (!abilities.isEmpty()) { 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; } } } else { logger.error("No abilities for continuous effect: " + effect.toString()); } break; default: layerEffects.add(effect); } } updateTimestamps(layerEffects); Collections.sort(layerEffects, Comparator.comparingLong(ContinuousEffect::getOrder)); return layerEffects; }
private void applyContinuousEffect(ContinuousEffect effect, Layer currentLayer, Game game) { Set<Ability> abilities = layeredEffects.getAbility(effect.getId()); for (Ability ability : abilities) { //effect.apply(currentLayer, SubLayer.NA, ability, game); if (isAbilityStillExists(game, ability, effect)) { effect.apply(currentLayer, SubLayer.NA, ability, game); } } }
private boolean isInactive(T effect, Game game) { Set<Ability> set = effectAbilityMap.get(effect.getId()); if (set == null) { logger.debug("No abilities for effect found: " + effect.toString());
Set<Ability> abilities = layeredEffects.getAbility(effect.getId()); for (Ability ability : abilities) { effect.apply(Layer.CopyEffects_1, SubLayer.NA, ability, game); Set<Ability> abilities = layeredEffects.getAbility(effect.getId()); for (Ability ability : abilities) { effect.apply(Layer.ControlChangingEffects_2, SubLayer.NA, ability, game); if (activeLayerEffects.contains(effect) && !appliedEffects.contains(effect.getId())) { // Effect does still exist and was not applied yet Set<UUID> dependentTo = effect.isDependentTo(layer); if (!appliedEffects.containsAll(dependentTo)) { Set<Ability> abilities = layeredEffects.getAbility(effect.getId()); for (Ability ability : abilities) { if (appliedAbilities == null || !appliedAbilities.contains(ability)) { appliedEffects.add(effect.getId()); if (appliedEffects.containsAll(entry.getValue())) { // all dependent to effects are applied now so apply the effect itself appliedAbilities = appliedEffectAbilities.get(entry.getKey()); abilities = layeredEffects.getAbility(entry.getKey().getId()); for (Ability ability : abilities) { if (appliedAbilities == null || !appliedAbilities.contains(ability)) { appliedEffects.add(entry.getKey().getId()); iterator.remove(); Set<Ability> abilities = layeredEffects.getAbility(effect.getId()); for (Ability ability : abilities) {