foul-magics/Mage/src/main/java/mage/watchers/common/ManaPaidSourceWatcher.java
Evan Kranzler 024c3081df
[BRC] Implement Rootpath Purifier (ready for review) (#10363)
* refactor check supertype methods

* change supertype to list to match card type

* refactor various subtype methods

* implement mageobjectattribute for supertype

* a few fixes

* [BRC] Implement Rootpath Purifier

* a few extra fixes

* more fixes

* add test for purifier
2023-05-13 10:48:07 -04:00

176 lines
6.4 KiB
Java

package mage.watchers.common;
import mage.MageObject;
import mage.ObjectColor;
import mage.constants.ManaType;
import mage.constants.SubType;
import mage.constants.WatcherScope;
import mage.constants.Zone;
import mage.game.Game;
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;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
/**
* Default watcher, no need to add it to ability
*
* @author TheElk801
*/
public class ManaPaidSourceWatcher extends Watcher {
private static final class ManaPaidTracker implements Serializable, Copyable<ManaPaidTracker> {
private int total = 0;
private int whiteSnow = 0;
private int blueSnow = 0;
private int blackSnow = 0;
private int redSnow = 0;
private int greenSnow = 0;
private int colorlessSnow = 0;
private int treasure = 0;
private int creature = 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;
this.creature = tracker.creature;
}
@Override
public ManaPaidTracker copy() {
return new ManaPaidTracker(this);
}
private void increment(MageObject sourceObject, ManaType manaType, Game game) {
total++;
if (sourceObject != null && sourceObject.hasSubtype(SubType.TREASURE, game)) {
treasure++;
}
if (sourceObject != null && sourceObject.isCreature(game)) {
creature++;
}
if (sourceObject != null && !sourceObject.isSnow(game)) {
return;
}
switch (manaType) {
case WHITE:
whiteSnow++;
break;
case BLUE:
blueSnow++;
break;
case BLACK:
blackSnow++;
break;
case RED:
redSnow++;
break;
case GREEN:
greenSnow++;
break;
case COLORLESS:
case GENERIC:
colorlessSnow++;
break;
}
}
private int getSnow() {
return whiteSnow + blueSnow + blackSnow + redSnow + greenSnow + colorlessSnow;
}
private boolean checkSnowColor(Spell spell, Game game) {
ObjectColor color = spell.getColor(game);
return color.isWhite() && whiteSnow > 0
|| color.isBlue() && blueSnow > 0
|| color.isBlack() && blackSnow > 0
|| color.isRed() && redSnow > 0
|| color.isGreen() && greenSnow > 0;
}
}
private static final ManaPaidTracker emptyTracker = new ManaPaidTracker();
private final Map<UUID, ManaPaidTracker> manaMap = new HashMap<>();
public ManaPaidSourceWatcher() {
super(WatcherScope.GAME);
}
@Override
public void watch(GameEvent event, Game game) {
switch (event.getType()) {
case ZONE_CHANGE:
if (((ZoneChangeEvent) event).getFromZone() == Zone.BATTLEFIELD
// Bug #9943 Memory Deluge cast from graveyard during the same turn
|| ((ZoneChangeEvent) event).getToZone() == Zone.GRAVEYARD) {
manaMap.remove(event.getTargetId());
}
return;
case MANA_PAID:
ManaPaidEvent manaEvent = (ManaPaidEvent) event;
manaMap.computeIfAbsent(manaEvent.getTargetId(), x -> new ManaPaidTracker())
.increment(manaEvent.getSourceObject(), manaEvent.getManaType(), game);
manaMap.computeIfAbsent(manaEvent.getSourcePaidId(), x -> new ManaPaidTracker())
.increment(manaEvent.getSourceObject(), manaEvent.getManaType(), game);
}
}
@Override
public void reset() {
super.reset();
manaMap.clear();
}
public static int getTotalPaid(UUID sourceId, Game game) {
ManaPaidSourceWatcher watcher = game.getState().getWatcher(ManaPaidSourceWatcher.class);
return watcher == null ? 0 : watcher.manaMap.getOrDefault(sourceId, emptyTracker).total;
}
public static int getTreasurePaid(UUID sourceId, Game game) {
ManaPaidSourceWatcher watcher = game.getState().getWatcher(ManaPaidSourceWatcher.class);
return watcher == null ? 0 : watcher.manaMap.getOrDefault(sourceId, emptyTracker).treasure;
}
public static int getCreaturePaid(UUID sourceId, Game game) {
ManaPaidSourceWatcher watcher = game.getState().getWatcher(ManaPaidSourceWatcher.class);
return watcher == null ? 0 : watcher.manaMap.getOrDefault(sourceId, emptyTracker).creature;
}
public static int getSnowPaid(UUID sourceId, Game game) {
ManaPaidSourceWatcher watcher = game.getState().getWatcher(ManaPaidSourceWatcher.class);
return watcher == null ? 0 : watcher.manaMap.getOrDefault(sourceId, emptyTracker).getSnow();
}
public static boolean checkSnowColor(Spell spell, Game game) {
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;
}
}