mirror of
https://github.com/magefree/mage.git
synced 2025-12-25 21:12:04 -08:00
* Fixed a problem with replacement effects that add counters were applied more than once to the same EnteresTheBattlefield event (fixes #2872).
This commit is contained in:
parent
94f77675ec
commit
d0bf77cedf
25 changed files with 302 additions and 104 deletions
|
|
@ -27,6 +27,9 @@
|
|||
*/
|
||||
package mage.abilities.effects;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
import mage.MageObject;
|
||||
import mage.abilities.*;
|
||||
import mage.abilities.keyword.SpliceOntoArcaneAbility;
|
||||
|
|
@ -49,10 +52,6 @@ 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;
|
||||
|
||||
/**
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
|
|
@ -691,8 +690,7 @@ public class ContinuousEffects implements Serializable {
|
|||
spliceAbilities.remove(selectedAbility);
|
||||
}
|
||||
}
|
||||
}
|
||||
while (!spliceAbilities.isEmpty() && controller.chooseUse(Outcome.Benefit, "Splice another card?", abilityToModify, game));
|
||||
} while (!spliceAbilities.isEmpty() && controller.chooseUse(Outcome.Benefit, "Splice another card?", abilityToModify, game));
|
||||
controller.revealCards("Spliced cards", cardsToReveal, game);
|
||||
}
|
||||
}
|
||||
|
|
@ -702,10 +700,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) {
|
||||
|
|
@ -752,7 +750,7 @@ public class ContinuousEffects implements Serializable {
|
|||
do {
|
||||
HashMap<ReplacementEffect, HashSet<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())) {
|
||||
HashSet<UUID> consumedAbilitiesIds = consumed.get(entry.getId());
|
||||
|
|
@ -933,7 +931,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());
|
||||
|
|
|
|||
|
|
@ -148,6 +148,7 @@ public class EntersBattlefieldEffect extends ReplacementEffectImpl {
|
|||
if (spell != null) {
|
||||
effect.setValue(SOURCE_CAST_SPELL_ABILITY, spell.getSpellAbility());
|
||||
}
|
||||
effect.setValue("appliedEffects", event.getAppliedEffects());
|
||||
effect.apply(game, source);
|
||||
}
|
||||
// }
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@
|
|||
*/
|
||||
package mage.abilities.effects.common;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.SpellAbility;
|
||||
import mage.abilities.effects.EntersBattlefieldEffect;
|
||||
|
|
@ -75,7 +77,8 @@ public class EntersBattlefieldWithXCountersEffect extends OneShotEffect {
|
|||
if (amount > 0) {
|
||||
Counter counterToAdd = counter.copy();
|
||||
counterToAdd.add(amount - counter.getCount());
|
||||
permanent.addCounters(counterToAdd, source, game);
|
||||
ArrayList<UUID> appliedEffects = (ArrayList<UUID>) this.getValue("appliedEffects");
|
||||
permanent.addCounters(counterToAdd, source, game, appliedEffects);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@
|
|||
*/
|
||||
package mage.abilities.effects.common.counter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.dynamicvalue.DynamicValue;
|
||||
import mage.abilities.dynamicvalue.common.StaticValue;
|
||||
|
|
@ -103,7 +105,8 @@ public class AddCountersSourceEffect extends OneShotEffect {
|
|||
countersToAdd--;
|
||||
}
|
||||
newCounter.add(countersToAdd);
|
||||
card.addCounters(newCounter, source, game);
|
||||
ArrayList<UUID> appliedEffects = (ArrayList<UUID>) this.getValue("appliedEffects");
|
||||
card.addCounters(newCounter, source, game, appliedEffects);
|
||||
if (informPlayers && !game.isSimulation()) {
|
||||
Player player = game.getPlayer(source.getControllerId());
|
||||
if (player != null) {
|
||||
|
|
@ -128,7 +131,8 @@ public class AddCountersSourceEffect extends OneShotEffect {
|
|||
}
|
||||
newCounter.add(countersToAdd);
|
||||
int before = permanent.getCounters(game).getCount(newCounter.getName());
|
||||
permanent.addCounters(newCounter, source, game);
|
||||
ArrayList<UUID> appliedEffects = (ArrayList<UUID>) this.getValue("appliedEffects");
|
||||
permanent.addCounters(newCounter, source, game, appliedEffects); // if used from a replacement effect, the basic event determines if an effect was already applied to an event
|
||||
if (informPlayers && !game.isSimulation()) {
|
||||
int amountAdded = permanent.getCounters(game).getCount(newCounter.getName()) - before;
|
||||
Player player = game.getPlayer(source.getControllerId());
|
||||
|
|
@ -150,12 +154,10 @@ public class AddCountersSourceEffect extends OneShotEffect {
|
|||
sb.append("put ");
|
||||
if (counter.getCount() > 1) {
|
||||
sb.append(CardUtil.numberToText(counter.getCount())).append(' ');
|
||||
} else if (amount.toString().equals("X") && amount.getMessage().isEmpty()) {
|
||||
sb.append("X ");
|
||||
} else {
|
||||
if (amount.toString().equals("X") && amount.getMessage().isEmpty()) {
|
||||
sb.append("X ");
|
||||
} else {
|
||||
sb.append("a ");
|
||||
}
|
||||
sb.append("a ");
|
||||
}
|
||||
sb.append(counter.getName().toLowerCase()).append(" counter on {this}");
|
||||
if (!amount.getMessage().isEmpty()) {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
package mage.abilities.keyword;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.EntersBattlefieldAbility;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
|
|
@ -71,7 +73,8 @@ class BloodthirstEffect extends OneShotEffect {
|
|||
if (watcher != null && watcher.conditionMet()) {
|
||||
Permanent permanent = game.getPermanentEntering(source.getSourceId());
|
||||
if (permanent != null) {
|
||||
permanent.addCounters(CounterType.P1P1.createInstance(amount), source, game);
|
||||
ArrayList<UUID> appliedEffects = (ArrayList<UUID>) this.getValue("appliedEffects"); // the basic event is the EntersBattlefieldEvent, so use already applied replacement effects from that event
|
||||
permanent.addCounters(CounterType.P1P1.createInstance(amount), source, game, appliedEffects);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
package mage.abilities.keyword;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.StaticAbility;
|
||||
import mage.abilities.common.DiesTriggeredAbility;
|
||||
|
|
@ -159,7 +161,8 @@ class ModularDistributeCounterEffect extends OneShotEffect {
|
|||
if (sourcePermanent != null && targetArtifact != null && player != null) {
|
||||
int numberOfCounters = sourcePermanent.getCounters(game).getCount(CounterType.P1P1);
|
||||
if (numberOfCounters > 0) {
|
||||
targetArtifact.addCounters(CounterType.P1P1.createInstance(numberOfCounters), source, game);
|
||||
ArrayList<UUID> appliedEffects = (ArrayList<UUID>) this.getValue("appliedEffects"); // the basic event is the EntersBattlefieldEvent, so use already applied replacement effects from that event
|
||||
targetArtifact.addCounters(CounterType.P1P1.createInstance(numberOfCounters), source, game, appliedEffects);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,13 +27,14 @@
|
|||
*/
|
||||
package mage.abilities.keyword;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.EntersBattlefieldAbility;
|
||||
import mage.abilities.dynamicvalue.DynamicValue;
|
||||
import mage.abilities.dynamicvalue.common.SunburstCount;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.cards.Card;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.counters.Counter;
|
||||
import mage.counters.CounterType;
|
||||
|
|
@ -97,8 +98,8 @@ class SunburstEffect extends OneShotEffect {
|
|||
counter = CounterType.CHARGE.createInstance(amount.calculate(game, source, this));
|
||||
}
|
||||
if (counter != null) {
|
||||
|
||||
permanent.addCounters(counter, source, game);
|
||||
ArrayList<UUID> appliedEffects = (ArrayList<UUID>) this.getValue("appliedEffects"); // the basic event is the EntersBattlefieldEvent, so use already applied replacement effects from that event
|
||||
permanent.addCounters(counter, source, game, appliedEffects);
|
||||
if (!game.isSimulation()) {
|
||||
Player player = game.getPlayer(source.getControllerId());
|
||||
if (player != null) {
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ class UnleashReplacementEffect extends ReplacementEffectImpl {
|
|||
if (!game.isSimulation()) {
|
||||
game.informPlayers(controller.getLogName() + " unleashes " + creature.getName());
|
||||
}
|
||||
creature.addCounters(CounterType.P1P1.createInstance(), source, game);
|
||||
creature.addCounters(CounterType.P1P1.createInstance(), source, game, event.getAppliedEffects());
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ public class MageDrawAction extends MageAction {
|
|||
*/
|
||||
protected int drawCard(Game game) {
|
||||
GameEvent event = GameEvent.getEvent(GameEvent.EventType.DRAW_CARD, player.getId(), player.getId());
|
||||
event.setAppliedEffects(appliedEffects);
|
||||
event.addAppliedEffects(appliedEffects);
|
||||
if (!game.replaceEvent(event)) {
|
||||
Card card = player.getLibrary().removeFromTop(game);
|
||||
if (card != null) {
|
||||
|
|
|
|||
|
|
@ -451,12 +451,19 @@ public class GameEvent implements Serializable {
|
|||
return type == EventType.CUSTOM_EVENT && this.customEventType.equals(customEventType);
|
||||
}
|
||||
|
||||
public void setAppliedEffects(ArrayList<UUID> appliedEffects) {
|
||||
if (this.appliedEffects == null) {
|
||||
this.appliedEffects = new ArrayList<>();
|
||||
}
|
||||
public void addAppliedEffects(ArrayList<UUID> appliedEffects) {
|
||||
if (appliedEffects != null) {
|
||||
this.appliedEffects.addAll(appliedEffects);
|
||||
}
|
||||
}
|
||||
|
||||
public void setAppliedEffects(ArrayList<UUID> appliedEffects) {
|
||||
if (appliedEffects != null) {
|
||||
if (this.appliedEffects.isEmpty()) {
|
||||
this.appliedEffects = appliedEffects; // Use object refecence to handle that an replacement effect can only be once applied to an event
|
||||
} else {
|
||||
this.appliedEffects.addAll(appliedEffects);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue