forked from External/mage
game: fixed wrong usage of batch events (related to #10870)
This commit is contained in:
parent
ba3b0e4cb7
commit
be4bff6097
6 changed files with 64 additions and 8 deletions
|
|
@ -1,5 +1,3 @@
|
|||
|
||||
|
||||
package mage.abilities;
|
||||
|
||||
import mage.MageObject;
|
||||
|
|
@ -9,6 +7,7 @@ import mage.game.events.GameEvent;
|
|||
import mage.game.events.NumberOfTriggersEvent;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.game.stack.Spell;
|
||||
import mage.util.CardUtil;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import java.util.*;
|
||||
|
|
@ -64,9 +63,10 @@ public class TriggeredAbilities extends ConcurrentHashMap<String, TriggeredAbili
|
|||
if (event == null || !game.getContinuousEffects().preventedByRuleModification(event, ability, game, false)) {
|
||||
if (object != null) {
|
||||
boolean controllerSet = false;
|
||||
Set<UUID> eventTargets = CardUtil.getEventTargets(event);
|
||||
if (ability.getZone() != Zone.COMMAND
|
||||
&& event != null
|
||||
&& event.getTargetId() != null
|
||||
&& !eventTargets.isEmpty()
|
||||
&& ability.isLeavesTheBattlefieldTrigger()
|
||||
&& game.getLKI().get(Zone.BATTLEFIELD) != null
|
||||
&& game.getLKI().get(Zone.BATTLEFIELD).containsKey(ability.getSourceId())) {
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ import mage.players.Player;
|
|||
import mage.util.CardUtil;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
|
|
@ -44,7 +45,7 @@ public abstract class TriggeredAbilityImpl extends AbilityImpl implements Trigge
|
|||
|
||||
// verify check: DoIfCostPaid effect already asks about action (optional), so no needs to ask it again in triggered ability
|
||||
if (effect instanceof DoIfCostPaid && (this.optional && ((DoIfCostPaid) effect).isOptional())) {
|
||||
throw new IllegalArgumentException("DoIfCostPaid effect must have only one optional settings, but it have two (trigger + DoIfCostPaid): " + this.getClass().getSimpleName());
|
||||
throw new IllegalArgumentException("DoIfCostPaid effect must have only one optional settings, but it have two (trigger + DoIfCostPaid): " + this.getClass().getSimpleName());
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -296,13 +297,16 @@ public abstract class TriggeredAbilityImpl extends AbilityImpl implements Trigge
|
|||
* latter triggers trigger from the game state after the move where the
|
||||
* Kozilek card is itself and has the ability.
|
||||
*/
|
||||
if (event == null || event.getTargetId() == null || !event.getTargetId().equals(getSourceId())) {
|
||||
|
||||
Set<UUID> eventTargets = CardUtil.getEventTargets(event);
|
||||
if (!eventTargets.contains(getSourceId())) {
|
||||
return super.isInUseableZone(game, source, event);
|
||||
}
|
||||
|
||||
switch (event.getType()) {
|
||||
case ZONE_CHANGE:
|
||||
ZoneChangeEvent zce = (ZoneChangeEvent) event;
|
||||
if (event.getTargetId().equals(getSourceId()) && !zce.getToZone().isPublicZone()) {
|
||||
if (eventTargets.contains(getSourceId()) && !zce.getToZone().isPublicZone()) {
|
||||
// If an ability triggers when the object that has it is put into a hidden zone from a graveyard,
|
||||
// that ability triggers from the graveyard, (such as Golgari Brownscale),
|
||||
// Yixlid Jailer will prevent that ability from triggering.
|
||||
|
|
|
|||
19
Mage/src/main/java/mage/game/events/BatchGameEvent.java
Normal file
19
Mage/src/main/java/mage/game/events/BatchGameEvent.java
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
package mage.game.events;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Game event with batch support (batch is an event that can contain multiple events, example: DAMAGED_BATCH_FOR_PLAYERS)
|
||||
* <p>
|
||||
* Used by game engine to support event lifecycle for triggers
|
||||
*
|
||||
* @author JayDi85
|
||||
*/
|
||||
public interface BatchGameEvent<T extends GameEvent> {
|
||||
|
||||
Set<T> getEvents();
|
||||
|
||||
Set<UUID> getTargets();
|
||||
|
||||
}
|
||||
|
|
@ -1,13 +1,15 @@
|
|||
package mage.game.events;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public abstract class DamagedBatchEvent extends GameEvent {
|
||||
public abstract class DamagedBatchEvent extends GameEvent implements BatchGameEvent<DamagedEvent> {
|
||||
|
||||
private final Class<? extends DamagedEvent> damageClazz;
|
||||
private final Set<DamagedEvent> events = new HashSet<>();
|
||||
|
|
@ -17,10 +19,19 @@ public abstract class DamagedBatchEvent extends GameEvent {
|
|||
this.damageClazz = damageClazz;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<DamagedEvent> getEvents() {
|
||||
return events;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<UUID> getTargets() {
|
||||
return events.stream()
|
||||
.map(GameEvent::getTargetId)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAmount() {
|
||||
return events
|
||||
|
|
@ -32,7 +43,7 @@ public abstract class DamagedBatchEvent extends GameEvent {
|
|||
@Override
|
||||
@Deprecated // events can store a diff value, so search it from events list instead
|
||||
public UUID getTargetId() {
|
||||
throw new IllegalStateException("Wrong code usage. Must search value from a getEvents list.");
|
||||
throw new IllegalStateException("Wrong code usage. Must search value from a getEvents list or use CardUtil.getEventTargets(event)");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -593,6 +593,11 @@ public class GameEvent implements Serializable {
|
|||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Some batch events can contain multiple events list, see BatchGameEvent for usage
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public UUID getTargetId() {
|
||||
return targetId;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ import mage.game.CardState;
|
|||
import mage.game.Game;
|
||||
import mage.game.GameState;
|
||||
import mage.game.command.Commander;
|
||||
import mage.game.events.BatchGameEvent;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.game.permanent.PermanentCard;
|
||||
|
|
@ -1840,4 +1841,20 @@ public final class CardUtil {
|
|||
targetToken.setCardNumber(newCardNumber);
|
||||
targetToken.setImageNumber(newImageNumber);
|
||||
}
|
||||
|
||||
/**
|
||||
* One single event can be a batch (contain multiple events)
|
||||
*
|
||||
* @param event
|
||||
* @return
|
||||
*/
|
||||
public static Set<UUID> getEventTargets(GameEvent event) {
|
||||
Set<UUID> res = new HashSet<>();
|
||||
if (event instanceof BatchGameEvent) {
|
||||
res.addAll(((BatchGameEvent<?>) event).getTargets());
|
||||
} else if (event != null && event.getTargetId() != null) {
|
||||
res.add(event.getTargetId());
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue