forked from External/mage
* Until end of your turn - fixed that effects discarded too early in multiplayer games (#5759, #5676);
Tests: added dozen tests for end of turn effects and related cards.
This commit is contained in:
parent
4288e45c23
commit
534037e095
22 changed files with 758 additions and 137 deletions
|
|
@ -1,9 +1,5 @@
|
|||
package mage.abilities.effects;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.stream.Collectors;
|
||||
import mage.MageObject;
|
||||
import mage.MageObjectReference;
|
||||
import mage.abilities.*;
|
||||
|
|
@ -31,6 +27,11 @@ import mage.players.Player;
|
|||
import mage.target.common.TargetCardInHand;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
|
|
@ -54,7 +55,7 @@ public class ContinuousEffects implements Serializable {
|
|||
private final Map<AsThoughEffectType, ContinuousEffectsList<AsThoughEffect>> asThoughEffectsMap = new EnumMap<>(AsThoughEffectType.class);
|
||||
public final List<ContinuousEffectsList<?>> allEffectsLists = new ArrayList<>();
|
||||
private final ApplyCountersEffect applyCounters;
|
||||
// private final PlaneswalkerRedirectionEffect planeswalkerRedirectionEffect;
|
||||
// private final PlaneswalkerRedirectionEffect planeswalkerRedirectionEffect;
|
||||
private final AuraReplacementEffect auraReplacementEffect;
|
||||
|
||||
private final List<ContinuousEffect> previous = new ArrayList<>();
|
||||
|
|
@ -134,18 +135,18 @@ public class ContinuousEffects implements Serializable {
|
|||
spliceCardEffects.removeEndOfCombatEffects();
|
||||
}
|
||||
|
||||
public synchronized void removeEndOfTurnEffects() {
|
||||
layeredEffects.removeEndOfTurnEffects();
|
||||
continuousRuleModifyingEffects.removeEndOfTurnEffects();
|
||||
replacementEffects.removeEndOfTurnEffects();
|
||||
preventionEffects.removeEndOfTurnEffects();
|
||||
requirementEffects.removeEndOfTurnEffects();
|
||||
restrictionEffects.removeEndOfTurnEffects();
|
||||
public synchronized void removeEndOfTurnEffects(Game game) {
|
||||
layeredEffects.removeEndOfTurnEffects(game);
|
||||
continuousRuleModifyingEffects.removeEndOfTurnEffects(game);
|
||||
replacementEffects.removeEndOfTurnEffects(game);
|
||||
preventionEffects.removeEndOfTurnEffects(game);
|
||||
requirementEffects.removeEndOfTurnEffects(game);
|
||||
restrictionEffects.removeEndOfTurnEffects(game);
|
||||
for (ContinuousEffectsList asThoughtlist : asThoughEffectsMap.values()) {
|
||||
asThoughtlist.removeEndOfTurnEffects();
|
||||
asThoughtlist.removeEndOfTurnEffects(game);
|
||||
}
|
||||
costModificationEffects.removeEndOfTurnEffects();
|
||||
spliceCardEffects.removeEndOfTurnEffects();
|
||||
costModificationEffects.removeEndOfTurnEffects(game);
|
||||
spliceCardEffects.removeEndOfTurnEffects(game);
|
||||
}
|
||||
|
||||
public synchronized void removeInactiveEffects(Game game) {
|
||||
|
|
@ -163,6 +164,20 @@ public class ContinuousEffects implements Serializable {
|
|||
spliceCardEffects.removeInactiveEffects(game);
|
||||
}
|
||||
|
||||
public synchronized void incYourTurnNumPlayed(Game game) {
|
||||
layeredEffects.incYourTurnNumPlayed(game);
|
||||
continuousRuleModifyingEffects.incYourTurnNumPlayed(game);
|
||||
replacementEffects.incYourTurnNumPlayed(game);
|
||||
preventionEffects.incYourTurnNumPlayed(game);
|
||||
requirementEffects.incYourTurnNumPlayed(game);
|
||||
restrictionEffects.incYourTurnNumPlayed(game);
|
||||
for (ContinuousEffectsList asThoughtlist : asThoughEffectsMap.values()) {
|
||||
asThoughtlist.incYourTurnNumPlayed(game);
|
||||
}
|
||||
costModificationEffects.incYourTurnNumPlayed(game);
|
||||
spliceCardEffects.incYourTurnNumPlayed(game);
|
||||
}
|
||||
|
||||
public synchronized List<ContinuousEffect> getLayeredEffects(Game game) {
|
||||
List<ContinuousEffect> layerEffects = new ArrayList<>();
|
||||
for (ContinuousEffect effect : layeredEffects) {
|
||||
|
|
@ -322,7 +337,7 @@ public class ContinuousEffects implements Serializable {
|
|||
}
|
||||
// boolean checkLKI = event.getType().equals(EventType.ZONE_CHANGE) || event.getType().equals(EventType.DESTROYED_PERMANENT);
|
||||
//get all applicable transient Replacement effects
|
||||
for (Iterator<ReplacementEffect> iterator = replacementEffects.iterator(); iterator.hasNext();) {
|
||||
for (Iterator<ReplacementEffect> iterator = replacementEffects.iterator(); iterator.hasNext(); ) {
|
||||
ReplacementEffect effect = iterator.next();
|
||||
if (!effect.checksEventType(event, game)) {
|
||||
continue;
|
||||
|
|
@ -354,7 +369,7 @@ public class ContinuousEffects implements Serializable {
|
|||
replaceEffects.put(effect, applicableAbilities);
|
||||
}
|
||||
}
|
||||
for (Iterator<PreventionEffect> iterator = preventionEffects.iterator(); iterator.hasNext();) {
|
||||
for (Iterator<PreventionEffect> iterator = preventionEffects.iterator(); iterator.hasNext(); ) {
|
||||
PreventionEffect effect = iterator.next();
|
||||
if (!effect.checksEventType(event, game)) {
|
||||
continue;
|
||||
|
|
@ -376,7 +391,7 @@ public class ContinuousEffects implements Serializable {
|
|||
}
|
||||
}
|
||||
if (!applicableAbilities.isEmpty()) {
|
||||
replaceEffects.put((ReplacementEffect) effect, applicableAbilities);
|
||||
replaceEffects.put(effect, applicableAbilities);
|
||||
}
|
||||
}
|
||||
return replaceEffects;
|
||||
|
|
@ -478,7 +493,6 @@ public class ContinuousEffects implements Serializable {
|
|||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param objectId
|
||||
* @param type
|
||||
* @param affectedAbility
|
||||
|
|
@ -697,10 +711,10 @@ public class ContinuousEffects implements Serializable {
|
|||
* 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 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
|
||||
* it's checked if the event would be replaced
|
||||
* @return
|
||||
*/
|
||||
public boolean preventedByRuleModification(GameEvent event, Ability targetAbility, Game game, boolean checkPlayableMode) {
|
||||
|
|
@ -747,7 +761,7 @@ public class ContinuousEffects implements Serializable {
|
|||
do {
|
||||
Map<ReplacementEffect, Set<Ability>> rEffects = getApplicableReplacementEffects(event, game);
|
||||
// Remove all consumed effects (ability dependant)
|
||||
for (Iterator<ReplacementEffect> it1 = rEffects.keySet().iterator(); it1.hasNext();) {
|
||||
for (Iterator<ReplacementEffect> it1 = rEffects.keySet().iterator(); it1.hasNext(); ) {
|
||||
ReplacementEffect entry = it1.next();
|
||||
if (consumed.containsKey(entry.getId()) /*&& !(entry instanceof CommanderReplacementEffect) */) { // 903.9.
|
||||
Set<UUID> consumedAbilitiesIds = consumed.get(entry.getId());
|
||||
|
|
@ -938,7 +952,7 @@ public class ContinuousEffects implements Serializable {
|
|||
|
||||
if (!waitingEffects.isEmpty()) {
|
||||
// check if waiting effects can be applied now
|
||||
for (Iterator<Map.Entry<ContinuousEffect, Set<UUID>>> iterator = waitingEffects.entrySet().iterator(); iterator.hasNext();) {
|
||||
for (Iterator<Map.Entry<ContinuousEffect, Set<UUID>>> iterator = waitingEffects.entrySet().iterator(); iterator.hasNext(); ) {
|
||||
Map.Entry<ContinuousEffect, Set<UUID>> entry = iterator.next();
|
||||
if (appliedEffects.containsAll(entry.getValue())) { // all dependent to effects are applied now so apply the effect itself
|
||||
appliedAbilities = appliedEffectAbilities.get(entry.getKey());
|
||||
|
|
@ -1059,9 +1073,7 @@ public class ContinuousEffects implements Serializable {
|
|||
final Card card = game.getPermanentOrLKIBattlefield(ability.getSourceId());
|
||||
if (!(effect instanceof BecomesFaceDownCreatureEffect)) {
|
||||
if (card != null) {
|
||||
if (!card.getAbilities(game).contains(ability)) {
|
||||
return false;
|
||||
}
|
||||
return card.getAbilities(game).contains(ability);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue