diff --git a/Mage/src/mage/abilities/effects/ContinuousEffect.java b/Mage/src/mage/abilities/effects/ContinuousEffect.java index bef98fbcf5..2088a57663 100644 --- a/Mage/src/mage/abilities/effects/ContinuousEffect.java +++ b/Mage/src/mage/abilities/effects/ContinuousEffect.java @@ -48,8 +48,8 @@ public interface ContinuousEffect extends Effect { boolean isDiscarded(); void discard(); Duration getDuration(); - Date getTimestamp(); - void setTimestamp(); + long getOrder(); + void setOrder(long order); boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game); boolean hasLayer(Layer layer); boolean isInactive(Ability source, Game game); diff --git a/Mage/src/mage/abilities/effects/ContinuousEffectImpl.java b/Mage/src/mage/abilities/effects/ContinuousEffectImpl.java index 49756d4f48..bb7311b98f 100644 --- a/Mage/src/mage/abilities/effects/ContinuousEffectImpl.java +++ b/Mage/src/mage/abilities/effects/ContinuousEffectImpl.java @@ -63,7 +63,7 @@ public abstract class ContinuousEffectImpl extends EffectImpl implements Continu protected Duration duration; protected Layer layer; protected SubLayer sublayer; - protected Date timestamp; + protected long order; protected boolean used = false; protected boolean discarded = false; // for manual effect discard protected boolean affectedObjectsSet = false; @@ -76,7 +76,7 @@ public abstract class ContinuousEffectImpl extends EffectImpl implements Continu public ContinuousEffectImpl(Duration duration, Outcome outcome) { super(outcome); this.duration = duration; - this.timestamp = new Date(); + this.order = 0; this.effectType = EffectType.CONTINUOUS; } @@ -91,7 +91,7 @@ public abstract class ContinuousEffectImpl extends EffectImpl implements Continu this.duration = effect.duration; this.layer = effect.layer; this.sublayer = effect.sublayer; - this.timestamp = new Date(effect.timestamp.getTime()); + this.order = effect.order; this.used = effect.used; this.discarded = effect.discarded; this.affectedObjectsSet = effect.affectedObjectsSet; @@ -114,13 +114,13 @@ public abstract class ContinuousEffectImpl extends EffectImpl implements Continu } @Override - public Date getTimestamp() { - return timestamp; + public long getOrder() { + return order; } @Override - public void setTimestamp() { - this.timestamp = new Date(); + public void setOrder(long order) { + this.order = order; } @Override diff --git a/Mage/src/mage/abilities/effects/ContinuousEffects.java b/Mage/src/mage/abilities/effects/ContinuousEffects.java index cbe82a1564..4d2ec4f8e3 100644 --- a/Mage/src/mage/abilities/effects/ContinuousEffects.java +++ b/Mage/src/mage/abilities/effects/ContinuousEffects.java @@ -32,7 +32,6 @@ import java.io.Serializable; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; -import java.util.Date; import java.util.EnumMap; import java.util.HashMap; import java.util.HashSet; @@ -77,7 +76,7 @@ public class ContinuousEffects implements Serializable { private static final transient Logger logger = Logger.getLogger(ContinuousEffects.class); - private Date lastSetTimestamp; + private long order = 0; //transient Continuous effects private ContinuousEffectsList layeredEffects = new ContinuousEffectsList<>(); @@ -100,6 +99,7 @@ public class ContinuousEffects implements Serializable { // effect.id -> sourceId - which effect was added by which sourceId private final Map sources = new HashMap<>(); + private final ContinuousEffectSorter sorter = new ContinuousEffectSorter(); public ContinuousEffects() { applyCounters = new ApplyCountersEffect(); @@ -120,16 +120,14 @@ public class ContinuousEffects implements Serializable { restrictionEffects = effect.restrictionEffects.copy(); restrictionUntapNotMoreThanEffects = effect.restrictionUntapNotMoreThanEffects.copy(); for (Map.Entry> entry : effect.asThoughEffectsMap.entrySet()) { - asThoughEffectsMap.put(entry.getKey(), entry.getValue()); + asThoughEffectsMap.put(entry.getKey(), entry.getValue().copy()); } costModificationEffects = effect.costModificationEffects.copy(); spliceCardEffects = effect.spliceCardEffects.copy(); - for (Map.Entry entry : effect.sources.entrySet()) { - sources.put(entry.getKey(), entry.getValue()); - } + sources.putAll(effect.sources); collectAllEffects(); - lastSetTimestamp = effect.lastSetTimestamp; + order = effect.order; } private void collectAllEffects() { @@ -222,7 +220,7 @@ public class ContinuousEffects implements Serializable { updateTimestamps(layerEffects); - Collections.sort(layerEffects, new TimestampSorter()); + Collections.sort(layerEffects, sorter); return layerEffects; } @@ -234,21 +232,17 @@ public class ContinuousEffects implements Serializable { */ private void updateTimestamps(List layerEffects) { for (ContinuousEffect continuousEffect : layerEffects) { - // check if it's new, then set timestamp + // check if it's new, then set order if (!previous.contains(continuousEffect)) { - setUniqueTimesstamp(continuousEffect); + setOrder(continuousEffect); } } previous.clear(); previous.addAll(layerEffects); } - public void setUniqueTimesstamp(ContinuousEffect effect) { - do { - effect.setTimestamp(); - } - while (effect.getTimestamp().equals(lastSetTimestamp)); // prevent to set the same timestamp so logical order is saved - lastSetTimestamp = effect.getTimestamp(); + public void setOrder(ContinuousEffect effect) { + effect.setOrder(order++); } private List filterLayeredEffects(List effects, Layer layer) { @@ -1008,9 +1002,10 @@ public class ContinuousEffects implements Serializable { return !requirementEffects.isEmpty(); } } -class TimestampSorter implements Comparator { + +class ContinuousEffectSorter implements Comparator { @Override public int compare(ContinuousEffect one, ContinuousEffect two) { - return one.getTimestamp().compareTo(two.getTimestamp()); + return Long.compare(one.getOrder(), two.getOrder()); } } diff --git a/Mage/src/mage/game/GameImpl.java b/Mage/src/mage/game/GameImpl.java index 0dc6b9fe75..ae08c1d446 100644 --- a/Mage/src/mage/game/GameImpl.java +++ b/Mage/src/mage/game/GameImpl.java @@ -666,7 +666,7 @@ public abstract class GameImpl implements Game, Serializable { playerByOrder = players.getNext(this); } } - if (gameOver(null)) { + if (gameOver(null) && !isSimulation()) { winnerId = findWinnersAndLosers(); StringBuilder sb = new StringBuilder("GAME ended gameId: ").append(this.getId()).append(" "); int count = 0; @@ -1230,7 +1230,6 @@ public abstract class GameImpl implements Game, Serializable { ContinuousEffect newEffect = continuousEffect.copy(); newEffect.newId(); - newEffect.setTimestamp(); newEffect.init(newAbility, this); state.addEffect(newEffect, newAbility); @@ -1293,7 +1292,6 @@ public abstract class GameImpl implements Game, Serializable { CopyEffect newEffect = new CopyEffect(duration, permanent, copyToPermanent.getId()); newEffect.newId(); - newEffect.setTimestamp(); newEffect.setApplier(applier); newEffect.init(newAbility, this); diff --git a/Mage/src/mage/game/permanent/PermanentImpl.java b/Mage/src/mage/game/permanent/PermanentImpl.java index 56f7358f8a..fc48828b4c 100644 --- a/Mage/src/mage/game/permanent/PermanentImpl.java +++ b/Mage/src/mage/game/permanent/PermanentImpl.java @@ -573,11 +573,11 @@ public abstract class PermanentImpl extends CardImpl implements Permanent { for (Ability ability : this.getAbilities()) { for (Iterator ite = ability.getEffects(game, EffectType.CONTINUOUS).iterator(); ite.hasNext();) { ContinuousEffect effect = (ContinuousEffect) ite.next(); - game.getContinuousEffects().setUniqueTimesstamp(effect); + game.getContinuousEffects().setOrder(effect); // It's important is to update timestamp of the copied effect in ContinuousEffects because it does the action for (ContinuousEffect conEffect: game.getContinuousEffects().getLayeredEffects(game)) { if (conEffect.getId().equals(effect.getId())) { - game.getContinuousEffects().setUniqueTimesstamp(conEffect); + game.getContinuousEffects().setOrder(conEffect); } } }