forked from External/mage
Merge pull request #11492 from xenohedron/clean-watchers
refactor: align game default watchers with usage
This commit is contained in:
commit
b4a58a339d
84 changed files with 249 additions and 333 deletions
|
|
@ -17,7 +17,6 @@ public class AttacksFirstTimeTriggeredAbility extends TriggeredAbilityImpl {
|
|||
|
||||
public AttacksFirstTimeTriggeredAbility(Effect effect, boolean optional) {
|
||||
super(Zone.BATTLEFIELD, effect, optional);
|
||||
this.addWatcher(new AttackedThisTurnWatcher());
|
||||
setTriggerPhrase("Whenever {this} attacks for the first time each turn, ");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -46,7 +46,6 @@ public class CastSecondSpellTriggeredAbility extends TriggeredAbilityImpl {
|
|||
public CastSecondSpellTriggeredAbility(Zone zone, Effect effect, TargetController targetController,
|
||||
boolean optional, SetTargetPointer setTargetPointer) {
|
||||
super(zone, effect, optional);
|
||||
this.addWatcher(new CastSpellLastTurnWatcher());
|
||||
if (targetController == TargetController.YOU) {
|
||||
this.addHint(hint);
|
||||
}
|
||||
|
|
@ -147,4 +146,4 @@ enum SpellCastValue implements DynamicValue {
|
|||
public String getMessage() {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ package mage.abilities.condition.common;
|
|||
import mage.abilities.Ability;
|
||||
import mage.abilities.condition.Condition;
|
||||
import mage.game.Game;
|
||||
import mage.watchers.common.MorbidWatcher;
|
||||
import mage.watchers.common.CreaturesDiedWatcher;
|
||||
|
||||
/**
|
||||
* @author nantuko
|
||||
|
|
@ -13,7 +13,7 @@ public enum MorbidCondition implements Condition {
|
|||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
MorbidWatcher watcher = game.getState().getWatcher(MorbidWatcher.class);
|
||||
CreaturesDiedWatcher watcher = game.getState().getWatcher(CreaturesDiedWatcher.class);
|
||||
return watcher != null && watcher.conditionMet();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,10 +9,12 @@ import mage.watchers.common.DamageDoneWatcher;
|
|||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
|
||||
public class SourceDealtDamageCondition implements Condition {
|
||||
private final int value;
|
||||
|
||||
/**
|
||||
* Must add DamageDoneWatcher on card init
|
||||
*/
|
||||
public SourceDealtDamageCondition(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
|
@ -29,4 +31,4 @@ public class SourceDealtDamageCondition implements Condition {
|
|||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@ import mage.game.Game;
|
|||
import mage.watchers.common.PlayersAttackedThisTurnWatcher;
|
||||
|
||||
/**
|
||||
* Remember to add PlayersAttackedThisTurnWatcher to card init
|
||||
*
|
||||
* @author JayDi85
|
||||
*/
|
||||
public enum AttackedThisTurnOpponentsCount implements DynamicValue {
|
||||
|
|
|
|||
|
|
@ -8,8 +8,6 @@ import mage.game.Game;
|
|||
import mage.watchers.common.CardsDrawnThisTurnWatcher;
|
||||
|
||||
/**
|
||||
* Don't forget to add CardsDrawnThisTurnWatcher in card's definition
|
||||
*
|
||||
* @author TheElk801
|
||||
*/
|
||||
public enum CardsDrawnThisTurnDynamicValue implements DynamicValue {
|
||||
|
|
@ -45,4 +43,3 @@ public enum CardsDrawnThisTurnDynamicValue implements DynamicValue {
|
|||
return hint;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,7 +28,6 @@ public class BoastAbility extends ActivatedAbilityImpl {
|
|||
public BoastAbility(Effect effect, Cost cost) {
|
||||
super(Zone.BATTLEFIELD, effect, cost);
|
||||
this.maxActivationsPerTurn = 1;
|
||||
this.addWatcher(new AttackedThisTurnWatcher());
|
||||
this.condition = BoastCondition.instance;
|
||||
this.addHint(BoastHint.instance);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1336,16 +1336,11 @@ public abstract class GameImpl implements Game {
|
|||
|
||||
public void initGameDefaultWatchers() {
|
||||
List<Watcher> newWatchers = new ArrayList<>();
|
||||
newWatchers.add(new MorbidWatcher());
|
||||
newWatchers.add(new CastSpellLastTurnWatcher());
|
||||
newWatchers.add(new CastSpellYourLastTurnWatcher());
|
||||
newWatchers.add(new PlayerLostLifeWatcher());
|
||||
newWatchers.add(new PlayerLostLifeNonCombatWatcher());
|
||||
newWatchers.add(new BlockedAttackerWatcher());
|
||||
newWatchers.add(new DamageDoneWatcher());
|
||||
newWatchers.add(new PlanarRollWatcher());
|
||||
newWatchers.add(new PlanarRollWatcher()); // needed for RollDiceTest (planechase code needs improves)
|
||||
newWatchers.add(new AttackedThisTurnWatcher());
|
||||
newWatchers.add(new PlayersAttackedThisTurnWatcher());
|
||||
newWatchers.add(new CardsDrawnThisTurnWatcher());
|
||||
newWatchers.add(new ManaSpentToCastWatcher());
|
||||
newWatchers.add(new ManaPaidSourceWatcher());
|
||||
|
|
|
|||
|
|
@ -23,6 +23,9 @@ public class AttackedThisTurnWatcher extends Watcher {
|
|||
// issue with Robber of the Rich. it needs to check the subtype of the LKI of the permanent on the battlefield and this fails with MageObjectReference
|
||||
private final Set<Permanent> attackedThisTurnCreaturesPermanentLKI = new HashSet<>();
|
||||
|
||||
/**
|
||||
* Game default watcher
|
||||
*/
|
||||
public AttackedThisTurnWatcher() {
|
||||
super(WatcherScope.GAME);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package mage.watchers.common;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
|
@ -9,7 +8,6 @@ import mage.MageObjectReference;
|
|||
import mage.constants.WatcherScope;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.events.GameEvent.EventType;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.watchers.Watcher;
|
||||
|
||||
|
|
@ -21,6 +19,9 @@ public class BlockedAttackerWatcher extends Watcher {
|
|||
|
||||
private final Map<MageObjectReference, Set<MageObjectReference>> blockData = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Game default watcher
|
||||
*/
|
||||
public BlockedAttackerWatcher() {
|
||||
super(WatcherScope.GAME);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,9 @@ public class BlockingOrBlockedWatcher extends Watcher {
|
|||
|
||||
private final Map<MageObjectReference, Set<MageObjectReference>> blockerMap = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Game default watcher
|
||||
*/
|
||||
public BlockingOrBlockedWatcher() {
|
||||
super(WatcherScope.GAME);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,9 @@ public class CastSpellLastTurnWatcher extends Watcher {
|
|||
private int activePlayerPrevTurnCount = 0;
|
||||
private int activePlayerThisTurnCount = 0;
|
||||
|
||||
/**
|
||||
* Game default watcher
|
||||
*/
|
||||
public CastSpellLastTurnWatcher() {
|
||||
super(WatcherScope.GAME);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,59 +0,0 @@
|
|||
package mage.watchers.common;
|
||||
|
||||
import mage.constants.WatcherScope;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.watchers.Watcher;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author nantuko, BetaSteward_at_googlemail.com (spjspj)
|
||||
*/
|
||||
public class CastSpellYourLastTurnWatcher extends Watcher {
|
||||
|
||||
private final Map<UUID, Integer> amountOfSpellsCastOnPrevTurn = new HashMap<>();
|
||||
private final Map<UUID, Integer> amountOfSpellsCastOnCurrentTurn = new HashMap<>();
|
||||
private UUID lastActivePlayer = null;
|
||||
|
||||
public CastSpellYourLastTurnWatcher() {
|
||||
super(WatcherScope.GAME);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void watch(GameEvent event, Game game) {
|
||||
lastActivePlayer = game.getActivePlayerId();
|
||||
if (event.getType() == GameEvent.EventType.SPELL_CAST) {
|
||||
UUID playerId = event.getPlayerId();
|
||||
if (playerId != null && playerId.equals(lastActivePlayer)) {
|
||||
amountOfSpellsCastOnCurrentTurn.putIfAbsent(playerId, 0);
|
||||
amountOfSpellsCastOnCurrentTurn.compute(playerId, (k, a) -> a + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
super.reset();
|
||||
if (amountOfSpellsCastOnPrevTurn != null
|
||||
&& lastActivePlayer != null
|
||||
&& amountOfSpellsCastOnPrevTurn.get(lastActivePlayer) != null) {
|
||||
amountOfSpellsCastOnPrevTurn.remove(lastActivePlayer);
|
||||
}
|
||||
|
||||
amountOfSpellsCastOnPrevTurn.putAll(amountOfSpellsCastOnCurrentTurn);
|
||||
amountOfSpellsCastOnCurrentTurn.clear();
|
||||
lastActivePlayer = null;
|
||||
}
|
||||
|
||||
public Integer getAmountOfSpellsCastOnPlayersTurn(UUID playerId) {
|
||||
return amountOfSpellsCastOnPrevTurn.getOrDefault(playerId, 0);
|
||||
}
|
||||
//
|
||||
// @Override
|
||||
// public CastSpellYourLastTurnWatcher copy() {
|
||||
// return new CastSpellYourLastTurnWatcher(this);
|
||||
// }
|
||||
}
|
||||
|
|
@ -24,6 +24,9 @@ public class CommanderPlaysCountWatcher extends Watcher {
|
|||
private final Map<UUID, Integer> playsCount = new HashMap<>();
|
||||
private final Map<UUID, Integer> playerCount = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Game default watcher
|
||||
*/
|
||||
public CommanderPlaysCountWatcher() {
|
||||
super(WatcherScope.GAME);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,9 @@ public class CreaturesDiedWatcher extends Watcher {
|
|||
private final Map<UUID, Integer> amountOfCreaturesThatDiedByController = new HashMap<>();
|
||||
private final Map<UUID, Integer> amountOfCreaturesThatDiedByOwner = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Game default watcher
|
||||
*/
|
||||
public CreaturesDiedWatcher() {
|
||||
super(WatcherScope.GAME);
|
||||
}
|
||||
|
|
@ -34,6 +37,7 @@ public class CreaturesDiedWatcher extends Watcher {
|
|||
|| !zEvent.getTarget().isCreature(game)) {
|
||||
return;
|
||||
}
|
||||
condition = true;
|
||||
amountOfCreaturesThatDiedByController.compute(zEvent.getTarget().getControllerId(), CardUtil::setOrIncrementValue);
|
||||
amountOfCreaturesThatDiedByOwner.compute(zEvent.getTarget().getOwnerId(), CardUtil::setOrIncrementValue);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,9 @@ public class EndStepCountWatcher extends Watcher {
|
|||
|
||||
private final Map<UUID, Integer> playerMap = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Game default watcher
|
||||
*/
|
||||
public EndStepCountWatcher() {
|
||||
super(WatcherScope.GAME);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -110,6 +110,9 @@ public class ManaPaidSourceWatcher extends Watcher {
|
|||
private static final ManaPaidTracker emptyTracker = new ManaPaidTracker();
|
||||
private final Map<UUID, ManaPaidTracker> manaMap = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Game default watcher
|
||||
*/
|
||||
public ManaPaidSourceWatcher() {
|
||||
super(WatcherScope.GAME);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,9 @@ public class ManaSpentToCastWatcher extends Watcher {
|
|||
|
||||
private final Map<MageObjectReference, Mana> manaMap = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Game default watcher
|
||||
*/
|
||||
public ManaSpentToCastWatcher() {
|
||||
super(WatcherScope.GAME);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,31 +0,0 @@
|
|||
|
||||
package mage.watchers.common;
|
||||
|
||||
import mage.constants.WatcherScope;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.events.ZoneChangeEvent;
|
||||
import mage.watchers.Watcher;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
public class MorbidWatcher extends Watcher {
|
||||
|
||||
public MorbidWatcher() {
|
||||
super(WatcherScope.GAME);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void watch(GameEvent event, Game game) {
|
||||
if (condition) {
|
||||
return;
|
||||
}
|
||||
if (event.getType() == GameEvent.EventType.ZONE_CHANGE
|
||||
&& ((ZoneChangeEvent) event).isDiesEvent()
|
||||
&& ((ZoneChangeEvent) event).getTarget().isCreature(game)) {
|
||||
condition = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,65 +0,0 @@
|
|||
package mage.watchers.common;
|
||||
|
||||
import mage.constants.WatcherScope;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.watchers.Watcher;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author LevelX2 (spjspj)
|
||||
*/
|
||||
public class PermanentsEnteredBattlefieldYourLastTurnWatcher extends Watcher {
|
||||
|
||||
private final Map<UUID, List<Permanent>> enteringBattlefield = new HashMap<>();
|
||||
private final Map<UUID, List<Permanent>> enteringBattlefieldLastTurn = new HashMap<>();
|
||||
private UUID lastActivePlayer = null;
|
||||
|
||||
public PermanentsEnteredBattlefieldYourLastTurnWatcher() {
|
||||
super(WatcherScope.GAME);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void watch(GameEvent event, Game game) {
|
||||
lastActivePlayer = game.getActivePlayerId();
|
||||
|
||||
if (event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD) {
|
||||
Permanent perm = game.getPermanentEntering(event.getTargetId());
|
||||
if (perm == null) {
|
||||
perm = game.getPermanent(event.getTargetId());
|
||||
}
|
||||
if (perm != null) {
|
||||
List<Permanent> permanents;
|
||||
if (!enteringBattlefield.containsKey(perm.getControllerId())) {
|
||||
permanents = new ArrayList<>();
|
||||
enteringBattlefield.put(perm.getControllerId(), permanents);
|
||||
} else {
|
||||
permanents = enteringBattlefield.get(perm.getControllerId());
|
||||
}
|
||||
permanents.add(perm.copy()); // copy needed because attributes like color could be changed later
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
super.reset();
|
||||
if (enteringBattlefieldLastTurn != null
|
||||
&& lastActivePlayer != null
|
||||
&& enteringBattlefieldLastTurn.get(lastActivePlayer) != null) {
|
||||
enteringBattlefieldLastTurn.remove(lastActivePlayer);
|
||||
}
|
||||
enteringBattlefieldLastTurn.putAll(enteringBattlefield);
|
||||
enteringBattlefield.clear();
|
||||
lastActivePlayer = null;
|
||||
}
|
||||
|
||||
public List<Permanent> getPermanentsEnteringOnPlayersLastTurn(Game game, UUID playerId) {
|
||||
if (game.isActivePlayer(playerId)) {
|
||||
return enteringBattlefield.get(playerId);
|
||||
}
|
||||
return enteringBattlefieldLastTurn.get(playerId);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,71 +0,0 @@
|
|||
package mage.watchers.common;
|
||||
|
||||
import mage.constants.WatcherScope;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.players.Player;
|
||||
import mage.watchers.Watcher;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
/*
|
||||
* Counts amount of life lost from noncombat sources current or last turn by players.
|
||||
* This watcher is automatically started in gameImpl.init for each game
|
||||
*
|
||||
* @author NinthWorld
|
||||
*/
|
||||
public class PlayerLostLifeNonCombatWatcher extends Watcher {
|
||||
|
||||
private final Map<UUID, Integer> amountOfLifeLostThisTurn = new HashMap<>();
|
||||
private final Map<UUID, Integer> amountOfLifeLostLastTurn = new HashMap<>();
|
||||
|
||||
public PlayerLostLifeNonCombatWatcher() {
|
||||
super(WatcherScope.GAME);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void watch(GameEvent event, Game game) {
|
||||
// non combat lose life
|
||||
if (event.getType() == GameEvent.EventType.LOST_LIFE && !event.getFlag()) {
|
||||
UUID playerId = event.getPlayerId();
|
||||
if (playerId != null) {
|
||||
Integer amount = amountOfLifeLostThisTurn.get(playerId);
|
||||
if (amount == null) {
|
||||
amount = event.getAmount();
|
||||
} else {
|
||||
amount = amount + event.getAmount();
|
||||
}
|
||||
amountOfLifeLostThisTurn.put(playerId, amount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int getLiveLost(UUID playerId) {
|
||||
return amountOfLifeLostThisTurn.getOrDefault(playerId, 0);
|
||||
}
|
||||
|
||||
public int getAllOppLifeLost(UUID playerId, Game game) {
|
||||
int amount = 0;
|
||||
for (UUID opponentId : this.amountOfLifeLostThisTurn.keySet()) {
|
||||
Player opponent = game.getPlayer(opponentId);
|
||||
if (opponent != null && opponent.hasOpponent(playerId, game)) {
|
||||
amount += this.amountOfLifeLostThisTurn.getOrDefault(opponentId, 0);
|
||||
}
|
||||
}
|
||||
return amount;
|
||||
}
|
||||
|
||||
public int getLiveLostLastTurn(UUID playerId) {
|
||||
return amountOfLifeLostLastTurn.getOrDefault(playerId, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
super.reset();
|
||||
amountOfLifeLostLastTurn.clear();
|
||||
amountOfLifeLostLastTurn.putAll(amountOfLifeLostThisTurn);
|
||||
amountOfLifeLostThisTurn.clear();
|
||||
}
|
||||
}
|
||||
|
|
@ -21,6 +21,9 @@ public class PlayerLostLifeWatcher extends Watcher {
|
|||
private final Map<UUID, Integer> amountOfLifeLostThisTurn = new HashMap<>();
|
||||
private final Map<UUID, Integer> amountOfLifeLostLastTurn = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Game default watcher
|
||||
*/
|
||||
public PlayerLostLifeWatcher() {
|
||||
super(WatcherScope.GAME);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,9 @@ public class SpellsCastWatcher extends Watcher {
|
|||
private final Map<UUID, List<Spell>> spellsCastFromGraveyard = new HashMap<>();
|
||||
private int nonCreatureSpells;
|
||||
|
||||
/**
|
||||
* Game default watcher
|
||||
*/
|
||||
public SpellsCastWatcher() {
|
||||
super(WatcherScope.GAME);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,9 @@ public class TemptedByTheRingWatcher extends Watcher {
|
|||
|
||||
private final Map<UUID, Integer> map = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Game default watcher
|
||||
*/
|
||||
public TemptedByTheRingWatcher() {
|
||||
super(WatcherScope.GAME);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue