use of mage.watchers.Watcher in project mage by magefree.
the class MetzaliTowerOfTriumphEffect method apply.
@Override
public boolean apply(Game game, Ability source) {
Watcher watcher = game.getState().getWatcher(AttackedThisTurnWatcher.class);
if (watcher instanceof AttackedThisTurnWatcher) {
Set<MageObjectReference> attackedThisTurn = ((AttackedThisTurnWatcher) watcher).getAttackedThisTurnCreatures();
List<Permanent> available = new ArrayList<>();
for (MageObjectReference mor : attackedThisTurn) {
Permanent permanent = mor.getPermanent(game);
if (permanent != null && permanent.isCreature(game)) {
available.add(permanent);
}
}
if (!available.isEmpty()) {
Permanent permanent = available.get(RandomUtil.nextInt(available.size()));
if (permanent != null) {
permanent.destroy(source, game, false);
}
}
return true;
}
return false;
}
use of mage.watchers.Watcher in project mage by magefree.
the class VerifyCardDataTest method test_checkWatcherCopyMethods.
@Test
public void test_checkWatcherCopyMethods() {
Collection<String> errorsList = new ArrayList<>();
Collection<String> warningsList = new ArrayList<>();
Reflections reflections = new Reflections("mage.");
Set<Class<? extends Watcher>> watcherClassesList = reflections.getSubTypesOf(Watcher.class);
for (Class<? extends Watcher> watcherClass : watcherClassesList) {
// only watcher class can be extended (e.g. final)
if (!watcherClass.getSuperclass().equals(Watcher.class)) {
errorsList.add("Error: only Watcher class can be extended: " + watcherClass.getName());
}
// no copy methods
try {
Method m = watcherClass.getMethod("copy");
if (!m.getGenericReturnType().getTypeName().equals("T")) {
errorsList.add("Error: copy() method must be deleted from watcher class: " + watcherClass.getName());
}
} catch (NoSuchMethodException e) {
errorsList.add("Error: can't find copy() method in watcher class: " + watcherClass.getName());
}
// no constructor for copy
try {
Constructor<? extends Watcher> constructor = watcherClass.getDeclaredConstructor(watcherClass);
errorsList.add("Error: copy constructor is not allowed in watcher class: " + watcherClass.getName());
} catch (NoSuchMethodException e) {
// all fine, no needs in copy constructors
}
// errors on create
try {
List<?> constructors = Arrays.asList(watcherClass.getDeclaredConstructors());
Constructor<? extends Watcher> constructor = (Constructor<? extends Watcher>) constructors.get(0);
Object[] args = new Object[constructor.getParameterCount()];
for (int index = 0; index < constructor.getParameterTypes().length; index++) {
Class<?> parameterType = constructor.getParameterTypes()[index];
if (parameterType.getSimpleName().equalsIgnoreCase("boolean")) {
args[index] = false;
} else {
args[index] = null;
}
}
constructor.setAccessible(true);
Watcher w1 = constructor.newInstance(args);
// errors on copy
try {
Watcher w2 = w1.copy();
if (w2 == null) {
errorsList.add("Error: can't copy watcher with unknown error, look at error logs above: " + watcherClass.getName());
}
} catch (Exception e) {
errorsList.add("Error: can't copy watcher: " + watcherClass.getName() + " (" + e.getMessage() + ")");
}
} catch (Exception e) {
errorsList.add("Error: can't create watcher: " + watcherClass.getName() + " (" + e.getMessage() + ")");
}
}
printMessages(warningsList);
printMessages(errorsList);
if (errorsList.size() > 0) {
Assert.fail("Found watcher errors: " + errorsList.size());
}
}
use of mage.watchers.Watcher in project mage by magefree.
the class PakoArcaneRetrieverWatcher method apply.
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
PakoArcaneRetrieverWatcher watcher = game.getState().getWatcher(PakoArcaneRetrieverWatcher.class);
if (controller == null || watcher == null) {
return false;
}
Cards cards = new CardsImpl();
game.getState().getPlayersInRange(controller.getId(), game).stream().map(game::getPlayer).map(Player::getLibrary).map(library -> library.getFromTop(game)).forEach(cards::add);
controller.moveCards(cards, Zone.EXILED, source, game);
cards.removeIf(cardId -> game.getState().getZone(cardId) != Zone.EXILED);
int counters = cards.count(StaticFilters.FILTER_CARD_NON_CREATURE, game);
if (cards.isEmpty()) {
return true;
}
cards.getCards(game).stream().filter(card -> card.addCounters(CounterType.FETCH.createInstance(), source.getControllerId(), source, game)).filter(card -> !card.isCreature(game)).forEach(card -> watcher.addCard(controller.getId(), card, game));
Permanent permanent = game.getPermanent(source.getSourceId());
if (permanent == null || counters == 0) {
return true;
}
return permanent.addCounters(CounterType.P1P1.createInstance(counters), source.getControllerId(), source, game);
}
use of mage.watchers.Watcher in project mage by magefree.
the class GameState method addAbility.
/**
* Abilities that are applied to other objects or applied for a certain time
* span
*
* @param ability
* @param sourceId - if source object can be moved between zones then you
* must set it here (each game cycle clear all source related triggers)
* @param attachedTo
*/
public void addAbility(Ability ability, UUID sourceId, MageObject attachedTo) {
if (ability instanceof StaticAbility) {
for (UUID modeId : ability.getModes().getSelectedModes()) {
Mode mode = ability.getModes().get(modeId);
for (Effect effect : mode.getEffects()) {
if (effect instanceof ContinuousEffect) {
addEffect((ContinuousEffect) effect, sourceId, ability);
}
}
}
} else if (ability instanceof TriggeredAbility) {
addTrigger((TriggeredAbility) ability, sourceId, attachedTo);
}
// Workaround to prevent ConcurrentModificationException, not clear to me why this is happening now
List<Watcher> watcherList = new ArrayList<>(ability.getWatchers());
for (Watcher watcher : watcherList) {
// TODO: Check that watcher for commanderAbility (where attachedTo = null) also work correctly
UUID controllerId = ability.getControllerId();
if (attachedTo instanceof Card) {
controllerId = ((Card) attachedTo).getOwnerId();
} else if (attachedTo instanceof Controllable) {
controllerId = ((Controllable) attachedTo).getControllerId();
}
watcher.setControllerId(controllerId);
watcher.setSourceId(attachedTo == null ? ability.getSourceId() : attachedTo.getId());
watchers.add(watcher);
}
for (Ability sub : ability.getSubAbilities()) {
addAbility(sub, sourceId, attachedTo);
}
}
use of mage.watchers.Watcher in project mage by magefree.
the class GameState method addDelayedTriggeredAbility.
public void addDelayedTriggeredAbility(DelayedTriggeredAbility ability) {
this.delayed.add(ability);
// Workaround to prevent ConcurrentModificationException, not clear to me why this is happening now
List<Watcher> watcherList = new ArrayList<>(ability.getWatchers());
for (Watcher watcher : watcherList) {
watcher.setControllerId(ability.getControllerId());
watcher.setSourceId(ability.getSourceId());
this.watchers.add(watcher);
}
}
Aggregations