mirror of
https://github.com/correl/mage.git
synced 2024-11-28 19:19:55 +00:00
* Mana pay to cast - fixed random values in games with AI (example: Marath, Will of the Wild, see #8204);
This commit is contained in:
parent
3a8e04f2bc
commit
473a81e13c
3 changed files with 73 additions and 1 deletions
|
@ -3,6 +3,9 @@ package org.mage.test.cards.single.c13;
|
|||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import mage.counters.CounterType;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.watchers.common.ManaPaidSourceWatcher;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestCommanderDuelBase;
|
||||
|
||||
|
@ -31,6 +34,32 @@ public class MarathWillOfTheWildTest extends CardTestCommanderDuelBase {
|
|||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
checkPermanentCounters("after first cast must have 3x counters", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Marath, Will of the Wild", CounterType.P1P1, 3);
|
||||
|
||||
// COPY WATCHER testing (e.g. rollback compatible)
|
||||
runCode("test copy watcher", 1, PhaseStep.PRECOMBAT_MAIN, playerA, (info, player, game) -> {
|
||||
ManaPaidSourceWatcher watcher = game.getState().getWatcher(ManaPaidSourceWatcher.class);
|
||||
Permanent perm = game.getBattlefield().getAllPermanents()
|
||||
.stream()
|
||||
.filter(p -> p.getName().equals("Marath, Will of the Wild"))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
Assert.assertNotNull(perm);
|
||||
|
||||
// check correct copy
|
||||
int before = watcher.testsReturnTotal(perm);
|
||||
Assert.assertEquals("original must have 3x", 3, before);
|
||||
ManaPaidSourceWatcher copiedWatcher = watcher.copy();
|
||||
int after = copiedWatcher.testsReturnTotal(perm);
|
||||
Assert.assertEquals("copied must have 3x", before, after);
|
||||
|
||||
// check correct refs and changes
|
||||
// simulate ai games (changes in copied watcher must not touch original watcher)
|
||||
copiedWatcher.testsIncrementManaAmount(game, perm);
|
||||
int afterChangeCopied = copiedWatcher.testsReturnTotal(perm);
|
||||
int afterChangeOriginal = watcher.testsReturnTotal(perm);
|
||||
Assert.assertEquals("after change, copied", 4, afterChangeCopied);
|
||||
Assert.assertEquals("after change, original", 3, afterChangeOriginal);
|
||||
});
|
||||
|
||||
// kill
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", "Marath, Will of the Wild");
|
||||
setChoice(playerA, true); // move to command
|
||||
|
|
|
@ -5,6 +5,7 @@ import mage.constants.WatcherScope;
|
|||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.players.PlayerList;
|
||||
import mage.util.Copyable;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
@ -142,6 +143,14 @@ public abstract class Watcher implements Serializable {
|
|||
Cards list = e.getValue().copy();
|
||||
target.put(e.getKey(), list);
|
||||
}
|
||||
} else if (Arrays.stream(((Class) valueType).getInterfaces()).anyMatch(c -> c.equals(Copyable.class))) {
|
||||
Map<Object, Copyable> source = (Map<Object, Copyable>) field.get(this);
|
||||
Map<Object, Copyable> target = (Map<Object, Copyable>) field.get(watcher);
|
||||
target.clear();
|
||||
for (Map.Entry<Object, Copyable> e : source.entrySet()) {
|
||||
Copyable object = (Copyable) e.getValue().copy();
|
||||
target.put(e.getKey(), object);
|
||||
}
|
||||
} else if (valueType.getTypeName().contains("List")) {
|
||||
Map<Object, List<Object>> source = (Map<Object, List<Object>>) field.get(this);
|
||||
Map<Object, List<Object>> target = (Map<Object, List<Object>>) field.get(watcher);
|
||||
|
@ -161,6 +170,8 @@ public abstract class Watcher implements Serializable {
|
|||
target.put(e.getKey(), map);
|
||||
}
|
||||
} else {
|
||||
// TODO: add additional tests to find unsupported watcher data
|
||||
|
||||
((Map) field.get(watcher)).putAll((Map) field.get(this));
|
||||
}
|
||||
} else if (field.getType() == List.class) {
|
||||
|
|
|
@ -11,6 +11,7 @@ import mage.game.events.GameEvent;
|
|||
import mage.game.events.ManaPaidEvent;
|
||||
import mage.game.events.ZoneChangeEvent;
|
||||
import mage.game.stack.Spell;
|
||||
import mage.util.Copyable;
|
||||
import mage.watchers.Watcher;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
@ -25,7 +26,8 @@ import java.util.UUID;
|
|||
*/
|
||||
public class ManaPaidSourceWatcher extends Watcher {
|
||||
|
||||
private static final class ManaPaidTracker implements Serializable {
|
||||
private static final class ManaPaidTracker implements Serializable, Copyable<ManaPaidTracker> {
|
||||
|
||||
private int total = 0;
|
||||
private int whiteSnow = 0;
|
||||
private int blueSnow = 0;
|
||||
|
@ -35,6 +37,26 @@ public class ManaPaidSourceWatcher extends Watcher {
|
|||
private int colorlessSnow = 0;
|
||||
private int treasure = 0;
|
||||
|
||||
private ManaPaidTracker() {
|
||||
super();
|
||||
}
|
||||
|
||||
private ManaPaidTracker(final ManaPaidTracker tracker) {
|
||||
this.total = tracker.total;
|
||||
this.whiteSnow = tracker.whiteSnow;
|
||||
this.blueSnow = tracker.blueSnow;
|
||||
this.blackSnow = tracker.blackSnow;
|
||||
this.redSnow = tracker.redSnow;
|
||||
this.greenSnow = tracker.greenSnow;
|
||||
this.colorlessSnow = tracker.colorlessSnow;
|
||||
this.treasure = tracker.treasure;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ManaPaidTracker copy() {
|
||||
return new ManaPaidTracker(this);
|
||||
}
|
||||
|
||||
private void increment(MageObject sourceObject, ManaType manaType, Game game) {
|
||||
total++;
|
||||
if (sourceObject.hasSubtype(SubType.TREASURE, game)) {
|
||||
|
@ -129,4 +151,14 @@ public class ManaPaidSourceWatcher extends Watcher {
|
|||
ManaPaidSourceWatcher watcher = game.getState().getWatcher(ManaPaidSourceWatcher.class);
|
||||
return watcher != null && watcher.manaMap.getOrDefault(spell.getSpellAbility().getId(), emptyTracker).checkSnowColor(spell, game);
|
||||
}
|
||||
|
||||
public void testsIncrementManaAmount(Game game, MageObject mageObject) {
|
||||
// for tests only (logic here: change data in tracker like real event do)
|
||||
this.manaMap.getOrDefault(mageObject.getId(), null).increment(mageObject, ManaType.RED, game);
|
||||
}
|
||||
|
||||
public int testsReturnTotal(MageObject mageObject) {
|
||||
// for tests only
|
||||
return this.manaMap.getOrDefault(mageObject.getId(), null).total;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue