mirror of
https://github.com/magefree/mage.git
synced 2025-12-21 02:52:02 -08:00
refactor: shared logic for diff implementation of isInUseableZone, improved docs and readability;
This commit is contained in:
parent
57ef74da90
commit
d49ff89a81
76 changed files with 285 additions and 273 deletions
|
|
@ -103,7 +103,7 @@ class AjanisLastStandTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
|
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
|
||||||
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
|
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -157,7 +157,7 @@ class AthreosDiesCreatureTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
|
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
|
||||||
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
|
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -95,7 +95,7 @@ class AvacynsCollarTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
|
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
|
||||||
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
|
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -78,7 +78,7 @@ class BereavementTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
|
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
|
||||||
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
|
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -95,7 +95,7 @@ class DeathTyrantTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
|
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
|
||||||
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
|
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,7 @@ class DeathsPresenceTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
|
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
|
||||||
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
|
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -103,7 +103,7 @@ class DiregrafCaptainTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
|
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
|
||||||
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
|
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -92,7 +92,7 @@ class FalkenrathNobleTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
|
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
|
||||||
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
|
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -97,8 +97,8 @@ class GraveBetrayalTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
|
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
|
||||||
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
|
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -77,8 +77,8 @@ class GravePactTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
|
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
|
||||||
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
|
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -86,8 +86,8 @@ class GutterGrimeTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
|
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
|
||||||
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
|
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -109,7 +109,7 @@ class HatefulEidolonTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
|
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
|
||||||
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
|
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -94,7 +94,7 @@ class InfestedThrinaxTriggeredAbility extends DelayedTriggeredAbility {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
|
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
|
||||||
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
|
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -101,8 +101,8 @@ class LuminousBroodmothTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
|
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
|
||||||
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
|
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -103,8 +103,8 @@ class LyndeCheerfulTormentorCurseDiesTriggeredAbility extends TriggeredAbilityIm
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
|
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
|
||||||
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
|
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -104,8 +104,8 @@ class MarchesaTheBlackRoseTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
|
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
|
||||||
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
|
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -206,8 +206,8 @@ class MariTheKillingQuillCreatureDiesAbility extends TriggeredAbilityImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
|
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
|
||||||
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
|
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -91,8 +91,8 @@ class MartyrsBondTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
|
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
|
||||||
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
|
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -108,7 +108,7 @@ class MassacreGirlDelayedTriggeredAbility extends DelayedTriggeredAbility {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
|
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
|
||||||
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
|
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -85,7 +85,7 @@ class MassacreWurmTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
|
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
|
||||||
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
|
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -125,11 +125,11 @@ class MillicentRestlessRevenantTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
|
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
|
||||||
if (event.getType() == GameEvent.EventType.ZONE_CHANGE) {
|
if (event.getType() == GameEvent.EventType.ZONE_CHANGE) {
|
||||||
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
|
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
|
||||||
} else {
|
} else {
|
||||||
return super.isInUseableZone(game, source, event);
|
return super.isInUseableZone(game, sourceObject, event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -110,8 +110,8 @@ class MimicVatTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
|
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
|
||||||
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
|
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -78,7 +78,7 @@ class MolderBeastTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
|
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
|
||||||
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
|
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -94,7 +94,7 @@ class MycoidShepherdTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
|
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
|
||||||
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
|
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -96,7 +96,7 @@ class NecroskitterTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
|
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
|
||||||
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
|
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -98,7 +98,7 @@ class NetherTraitorTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
|
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
|
||||||
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
|
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -112,8 +112,8 @@ class NimDeathmantleTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
|
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
|
||||||
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
|
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -98,7 +98,7 @@ class OrahSkyclaveHierophantTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
|
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
|
||||||
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
|
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -110,8 +110,8 @@ class PatronOfTheVeinCreatureDiesTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
|
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
|
||||||
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
|
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -131,7 +131,7 @@ class PiasRevolutionTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
|
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
|
||||||
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
|
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -80,7 +80,7 @@ class ProperBurialTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
|
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
|
||||||
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
|
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -106,8 +106,8 @@ class PurgatoryTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
|
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
|
||||||
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
|
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -96,7 +96,7 @@ class RemembranceTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
|
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
|
||||||
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
|
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -114,11 +114,11 @@ class RhukHexgoldNabberTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
|
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
|
||||||
if (event.getType() == GameEvent.EventType.ZONE_CHANGE) {
|
if (event.getType() == GameEvent.EventType.ZONE_CHANGE) {
|
||||||
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
|
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
|
||||||
} else {
|
} else {
|
||||||
return super.isInUseableZone(game, source, event);
|
return super.isInUseableZone(game, sourceObject, event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -113,8 +113,8 @@ class RienneAngelOfRebirthTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
|
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
|
||||||
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
|
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,7 @@ class SacredGroundTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
|
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
|
||||||
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
|
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -80,8 +80,8 @@ class SangromancerFirstTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
|
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
|
||||||
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
|
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -94,7 +94,7 @@ class ScrapTrawlerTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
|
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
|
||||||
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
|
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -80,7 +80,7 @@ class ScrapheapTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
|
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
|
||||||
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
|
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -89,7 +89,7 @@ class SeerOfStolenSightTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
|
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
|
||||||
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
|
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -189,8 +189,8 @@ class ShelobChildOfUngoliantTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
|
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
|
||||||
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
|
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -83,7 +83,7 @@ class SlagstoneRefineryTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
|
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
|
||||||
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
|
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -92,7 +92,7 @@ class SlayersPlateTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
|
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
|
||||||
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
|
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -108,8 +108,8 @@ class SporogenesisTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
|
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
|
||||||
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
|
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -96,8 +96,8 @@ class SyrKonradTheGrimTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
|
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
|
||||||
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
|
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -109,8 +109,8 @@ class TheScorpionGodTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
|
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
|
||||||
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
|
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -171,8 +171,8 @@ class TheSkullsporeNexusTrigger extends TriggeredAbilityImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
|
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
|
||||||
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
|
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -102,8 +102,8 @@ class TianaShipsCaretakerTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
|
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
|
||||||
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
|
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -101,8 +101,8 @@ class VerdantSuccessionTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
|
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
|
||||||
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
|
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -78,7 +78,7 @@ class VillageCannibalsTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
|
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
|
||||||
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
|
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -70,8 +70,8 @@ class VindictiveVampireTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
|
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
|
||||||
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
|
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -81,7 +81,7 @@ class ViridianRevelTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
|
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
|
||||||
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
|
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -105,7 +105,7 @@ class XiraTheGoldenStingTriggeredAbility extends WhenTargetDiesDelayedTriggeredA
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
|
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
|
||||||
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
|
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -86,9 +86,6 @@ public interface Ability extends Controllable, Serializable {
|
||||||
* Gets the id of the object which put this ability in motion.
|
* Gets the id of the object which put this ability in motion.
|
||||||
* <p>
|
* <p>
|
||||||
* WARNING, MageSingleton abilities contains dirty data here, so you can't use sourceId with it
|
* WARNING, MageSingleton abilities contains dirty data here, so you can't use sourceId with it
|
||||||
*
|
|
||||||
* @return The {@link java.util.UUID} of the object this ability is
|
|
||||||
* associated with.
|
|
||||||
*/
|
*/
|
||||||
UUID getSourceId();
|
UUID getSourceId();
|
||||||
|
|
||||||
|
|
@ -358,16 +355,17 @@ public interface Ability extends Controllable, Serializable {
|
||||||
* - for leave battlefield triggers - keep default + set setLeavesTheBattlefieldTrigger(true)
|
* - for leave battlefield triggers - keep default + set setLeavesTheBattlefieldTrigger(true)
|
||||||
* - for dies triggers - override and use TriggeredAbilityImpl.isInUseableZoneDiesTrigger inside + set setLeavesTheBattlefieldTrigger(true)
|
* - for dies triggers - override and use TriggeredAbilityImpl.isInUseableZoneDiesTrigger inside + set setLeavesTheBattlefieldTrigger(true)
|
||||||
*
|
*
|
||||||
* @param source can be null for static continues effects checking like rules modification (example: Yixlid Jailer)
|
* @param sourceObject can be null for static continues effects checking like rules modification (example: Yixlid Jailer)
|
||||||
|
* @param event can be null for state base effects checking like "when you control seven or more" (example: Endrek Sahr, Master Breeder)
|
||||||
*/
|
*/
|
||||||
boolean isInUseableZone(Game game, MageObject source, GameEvent event);
|
boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the source object has currently the ability (e.g. The
|
* Returns true if the source object has currently the ability (e.g. The
|
||||||
* object can have lost all or some abilities for some time (e.g. Turn to
|
* object can have lost all or some abilities for some time (e.g. Turn to
|
||||||
* Frog)
|
* Frog)
|
||||||
*/
|
*/
|
||||||
boolean hasSourceObjectAbility(Game game, MageObject source, GameEvent event);
|
boolean hasSourceObjectAbility(Game game, MageObject sourceObject, GameEvent event);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the ability has a tap itself in their costs
|
* Returns true if the ability has a tap itself in their costs
|
||||||
|
|
@ -485,6 +483,7 @@ public interface Ability extends Controllable, Serializable {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds the source object regardless of its zcc. Can be LKI from battlefield in some cases.
|
* Finds the source object regardless of its zcc. Can be LKI from battlefield in some cases.
|
||||||
|
* Warning, do not use with singleton abilities
|
||||||
*/
|
*/
|
||||||
MageObject getSourceObject(Game game);
|
MageObject getSourceObject(Game game);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1175,35 +1175,31 @@ public abstract class AbilityImpl implements Ability {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
|
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
|
||||||
if (!this.hasSourceObjectAbility(game, source, event)) {
|
if (!this.hasSourceObjectAbility(game, sourceObject, event)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// workaround for singleton abilities like Flying
|
||||||
|
UUID affectedSourceId = getRealSourceObjectId(this, sourceObject);
|
||||||
|
|
||||||
// in command zone
|
// in command zone
|
||||||
if (zone == Zone.COMMAND) {
|
if (zone == Zone.COMMAND) {
|
||||||
if (this.getSourceId() == null) { // commander effects
|
if (affectedSourceId == null) {
|
||||||
|
// commander effects
|
||||||
return true;
|
return true;
|
||||||
}
|
} else {
|
||||||
MageObject object = game.getObject(this.getSourceId());
|
MageObject object = game.getObject(affectedSourceId);
|
||||||
// emblem/planes are always actual
|
// emblem/planes are always actual
|
||||||
if (object instanceof Emblem || object instanceof Dungeon || object instanceof Plane) {
|
if (object instanceof Emblem || object instanceof Dungeon || object instanceof Plane) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
UUID parameterSourceId;
|
|
||||||
// for singleton abilities like Flying we can't rely on abilities' source because it's only once in continuous effects
|
|
||||||
// so will use the sourceId of the object itself that came as a parameter if it is not null
|
|
||||||
if (this instanceof MageSingleton && source != null) {
|
|
||||||
parameterSourceId = source.getId();
|
|
||||||
} else {
|
|
||||||
parameterSourceId = getSourceId();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// on entering permanents - must use static abilities like it already on battlefield
|
// on entering permanents - must use static abilities like it already on battlefield
|
||||||
// example: Tatterkite enters without counters from Mikaeus, the Unhallowed
|
// example: Tatterkite enters without counters from Mikaeus, the Unhallowed
|
||||||
if (game.getPermanentEntering(parameterSourceId) != null && zone == Zone.BATTLEFIELD) {
|
if (game.getPermanentEntering(affectedSourceId) != null && zone == Zone.BATTLEFIELD) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1212,7 +1208,7 @@ public abstract class AbilityImpl implements Ability {
|
||||||
// any trigger conditions, and continuous effects that exist at that time are used to determine what the
|
// any trigger conditions, and continuous effects that exist at that time are used to determine what the
|
||||||
// trigger conditions are and what the objects involved in the event look like.
|
// trigger conditions are and what the objects involved in the event look like.
|
||||||
// ...
|
// ...
|
||||||
Zone sourceObjectZone = game.getState().getZone(parameterSourceId);
|
Zone sourceObjectZone = game.getState().getZone(affectedSourceId);
|
||||||
|
|
||||||
// 603.10.
|
// 603.10.
|
||||||
// ...
|
// ...
|
||||||
|
|
@ -1228,12 +1224,12 @@ public abstract class AbilityImpl implements Ability {
|
||||||
// TODO: research "put into a hand or library"
|
// TODO: research "put into a hand or library"
|
||||||
if (isTriggerCanFireAfterLeaveBattlefield(event)) {
|
if (isTriggerCanFireAfterLeaveBattlefield(event)) {
|
||||||
// permanents with normal triggers
|
// permanents with normal triggers
|
||||||
if (source instanceof Permanent) {
|
if (sourceObject instanceof Permanent) { // TODO: use affectedSourceObject here?
|
||||||
// support leaves-the-battlefield abilities
|
// support leaves-the-battlefield abilities
|
||||||
sourceObjectZone = Zone.BATTLEFIELD;
|
sourceObjectZone = Zone.BATTLEFIELD;
|
||||||
}
|
}
|
||||||
// permanents with continues effects like Yixlid Jailer, see related code "isInUseableZone(game, null"
|
// permanents with continues effects like Yixlid Jailer, see related code "isInUseableZone(game, null"
|
||||||
if (source == null && this instanceof StaticAbility) {
|
if (sourceObject == null && this instanceof StaticAbility) {
|
||||||
sourceObjectZone = Zone.BATTLEFIELD;
|
sourceObjectZone = Zone.BATTLEFIELD;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1267,6 +1263,7 @@ public abstract class AbilityImpl implements Ability {
|
||||||
// need research: is it ability's or event's task?
|
// need research: is it ability's or event's task?
|
||||||
// - ability's task: code like ability.setLookBackInTime
|
// - ability's task: code like ability.setLookBackInTime
|
||||||
// - event's task: code like current switch
|
// - event's task: code like current switch
|
||||||
|
// TODO: alternative solution: replace check by source.isLeavesTheBattlefieldTrigger?
|
||||||
switch (e.getType()) {
|
switch (e.getType()) {
|
||||||
case DESTROYED_PERMANENT:
|
case DESTROYED_PERMANENT:
|
||||||
case EXPLOITED_CREATURE:
|
case EXPLOITED_CREATURE:
|
||||||
|
|
@ -1279,31 +1276,43 @@ public abstract class AbilityImpl implements Ability {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
/**
|
||||||
public boolean hasSourceObjectAbility(Game game, MageObject source, GameEvent event) {
|
* Find real source object id from any ability (real and singleton)
|
||||||
// if source object have this ability
|
*/
|
||||||
// uses for ability.isInUseableZone
|
protected static UUID getRealSourceObjectId(Ability sourceAbility, MageObject sourceObject) {
|
||||||
// replacement and other continues effects can be without source, but active (must return true)
|
// In singleton abilities like Flying we can't rely on ability's source because it's init only once in continuous effects
|
||||||
|
|
||||||
MageObject object = source;
|
|
||||||
// for singleton abilities like Flying we can't rely on abilities' source because it's only once in continuous effects
|
|
||||||
// so will use the sourceId of the object itself that came as a parameter if it is not null
|
// so will use the sourceId of the object itself that came as a parameter if it is not null
|
||||||
|
if (sourceAbility instanceof MageSingleton && sourceObject != null) {
|
||||||
|
return sourceObject.getId();
|
||||||
|
} else {
|
||||||
|
return sourceAbility.getSourceId();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasSourceObjectAbility(Game game, MageObject sourceObject, GameEvent event) {
|
||||||
|
MageObject object = sourceObject;
|
||||||
if (object == null) {
|
if (object == null) {
|
||||||
object = game.getPermanentEntering(getSourceId());
|
object = game.getPermanentEntering(getSourceId());
|
||||||
if (object == null) {
|
if (object == null) {
|
||||||
object = game.getObject(getSourceId());
|
object = game.getObject(getSourceId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (object != null) {
|
|
||||||
|
if (object == null) {
|
||||||
|
// replacement and other continues effects can be without source, but active (must return true all time)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!object.hasAbility(this, game)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// phase in/out support
|
||||||
if (object instanceof Permanent) {
|
if (object instanceof Permanent) {
|
||||||
return object.hasAbility(this, game) && (
|
return ((Permanent) object).isPhasedIn() || this.getWorksPhasedOut();
|
||||||
((Permanent) object).isPhasedIn() || this.getWorksPhasedOut()
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
// cards and other objects
|
|
||||||
return object.hasAbility(this, game);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -209,7 +209,7 @@ public class TriggeredAbilities extends LinkedHashMap<String, TriggeredAbility>
|
||||||
if (ability.isInUseableZone(game, object, event)) {
|
if (ability.isInUseableZone(game, object, event)) {
|
||||||
if (event == null || !game.getContinuousEffects().preventedByRuleModification(event, ability, game, false)) {
|
if (event == null || !game.getContinuousEffects().preventedByRuleModification(event, ability, game, false)) {
|
||||||
if (object != null) {
|
if (object != null) {
|
||||||
boolean controllerSet = false;
|
boolean controllerSet = false; // TODO: wtf?!?!? Need rework whole "set" logic here
|
||||||
Set<UUID> eventTargets = CardUtil.getEventTargets(event);
|
Set<UUID> eventTargets = CardUtil.getEventTargets(event);
|
||||||
if (ability.getZone() != Zone.COMMAND
|
if (ability.getZone() != Zone.COMMAND
|
||||||
&& event != null
|
&& event != null
|
||||||
|
|
|
||||||
|
|
@ -72,6 +72,15 @@ public interface TriggeredAbility extends Ability {
|
||||||
* If true the game “looks back in time” to determine if those abilities trigger
|
* If true the game “looks back in time” to determine if those abilities trigger
|
||||||
* This has to be set, if the triggered ability has to check back in time if the permanent the ability is connected
|
* This has to be set, if the triggered ability has to check back in time if the permanent the ability is connected
|
||||||
* to had the ability on the battlefield while the trigger is checked
|
* to had the ability on the battlefield while the trigger is checked
|
||||||
|
* <p>
|
||||||
|
* 603.6c
|
||||||
|
* Leaves-the-battlefield abilities trigger when a permanent moves from the battlefield to another zone,
|
||||||
|
* or when a phased-in permanent leaves the game because its owner leaves the game. These are written as,
|
||||||
|
* but aren’t limited to, “When [this object] leaves the battlefield, . . .” or “Whenever [something] is put
|
||||||
|
* into a graveyard from the battlefield, . . . .” (See also rule 603.10.) An ability that attempts to do
|
||||||
|
* something to the card that left the battlefield checks for it only in the first zone that it went to.
|
||||||
|
* An ability that triggers when a card is put into a certain zone “from anywhere” is never treated as a
|
||||||
|
* leaves-the-battlefield ability, even if an object is put into that zone from the battlefield.
|
||||||
*/
|
*/
|
||||||
void setLeavesTheBattlefieldTrigger(boolean leavesTheBattlefieldTrigger);
|
void setLeavesTheBattlefieldTrigger(boolean leavesTheBattlefieldTrigger);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -348,50 +348,38 @@ public abstract class TriggeredAbilityImpl extends AbilityImpl implements Trigge
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
|
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
|
||||||
|
|
||||||
/**
|
// workaround for singleton abilities like Flying
|
||||||
* 603.6. Trigger events that involve objects changing zones are called
|
UUID affectedSourceId = getRealSourceObjectId(this, sourceObject);
|
||||||
* “zone-change triggers.” Many abilities with zone-change triggers
|
|
||||||
* attempt to do something to that object after it changes zones. During
|
|
||||||
* resolution, these abilities look for the object in the zone that it
|
|
||||||
* moved to. If the object is unable to be found in the zone it went to,
|
|
||||||
* the part of the ability attempting to do something to the object will
|
|
||||||
* fail to do anything. The ability could be unable to find the object
|
|
||||||
* because the object never entered the specified zone, because it left
|
|
||||||
* the zone before the ability resolved, or because it is in a zone that
|
|
||||||
* is hidden from a player, such as a library or an opponent's hand.
|
|
||||||
* (This rule applies even if the object leaves the zone and returns
|
|
||||||
* again before the ability resolves.) The most common zone-change
|
|
||||||
* triggers are enters-the-battlefield triggers and
|
|
||||||
* leaves-the-battlefield triggers.
|
|
||||||
*
|
|
||||||
* from:
|
|
||||||
* http://www.mtgsalvation.com/forums/magic-fundamentals/magic-rulings/magic-rulings-archives/537065-ixidron-and-kozilek
|
|
||||||
* There are two types of triggers that involve the graveyard: dies
|
|
||||||
* triggers (which are a subset of leave-the-battlefield triggers) and
|
|
||||||
* put into the graveyard from anywhere triggers.
|
|
||||||
*
|
|
||||||
* The former triggers trigger based on the game state prior to the move
|
|
||||||
* where the Kozilek permanent is face down and has no abilities. The
|
|
||||||
* latter triggers trigger from the game state after the move where the
|
|
||||||
* Kozilek card is itself and has the ability.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// process events from other objects
|
// 603.6
|
||||||
Set<UUID> eventTargets = CardUtil.getEventTargets(event);
|
// Trigger events that involve objects changing zones are called "zone-change triggers." Many abilities with
|
||||||
if (!eventTargets.contains(getSourceId())) {
|
// zone-change triggers attempt to do something to that object after it changes zones. During resolution,
|
||||||
return super.isInUseableZone(game, source, event);
|
// these abilities look for the object in the zone that it moved to. If the object is unable to be found
|
||||||
}
|
// in the zone it went to, the part of the ability attempting to do something to the object will fail to
|
||||||
|
// do anything. The ability could be unable to find the object because the object never entered the
|
||||||
|
// specified zone, because it left the zone before the ability resolved, or because it is in a zone that
|
||||||
|
// is hidden from a player, such as a library or an opponent’s hand. (This rule applies even if the
|
||||||
|
// object leaves the zone and returns again before the ability resolves.) The most common zone-change
|
||||||
|
// triggers are enters-the-battlefield triggers and leaves-the-battlefield triggers.
|
||||||
|
|
||||||
// process events from own object
|
// There are possible two different use cases:
|
||||||
|
// * look in current game state (normal events):
|
||||||
|
// * look back in time (leaves battlefield, dies, etc);
|
||||||
|
|
||||||
// inject process of "look back in time" events
|
// TODO: need sync or shared code with AbilityImpl.isInUseableZone
|
||||||
// TODO: need sync code with AbilityImpl.isInUseableZone
|
MageObject affectedSourceObject = sourceObject;
|
||||||
|
if (event == null) {
|
||||||
|
// state base triggers - use only actual state
|
||||||
|
} else {
|
||||||
|
// event triggers - can look back in time for some use cases
|
||||||
switch (event.getType()) {
|
switch (event.getType()) {
|
||||||
case ZONE_CHANGE:
|
case ZONE_CHANGE:
|
||||||
ZoneChangeEvent zce = (ZoneChangeEvent) event;
|
ZoneChangeEvent zce = (ZoneChangeEvent) event;
|
||||||
|
Set<UUID> eventTargets = CardUtil.getEventTargets(event);
|
||||||
if (eventTargets.contains(getSourceId()) && !zce.getToZone().isPublicZone()) {
|
if (eventTargets.contains(getSourceId()) && !zce.getToZone().isPublicZone()) {
|
||||||
|
// TODO: need research and share with AbilityImpl
|
||||||
// If an ability triggers when the object that has it is put into a hidden zone from a graveyard,
|
// 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),
|
// that ability triggers from the graveyard, (such as Golgari Brownscale),
|
||||||
// Yixlid Jailer will prevent that ability from triggering.
|
// Yixlid Jailer will prevent that ability from triggering.
|
||||||
|
|
@ -401,20 +389,20 @@ public abstract class TriggeredAbilityImpl extends AbilityImpl implements Trigge
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (isLeavesTheBattlefieldTrigger()) {
|
if (isLeavesTheBattlefieldTrigger() && game.checkShortLivingLKI(affectedSourceId, Zone.BATTLEFIELD)) {
|
||||||
source = zce.getTarget();
|
affectedSourceObject = game.getLastKnownInformation(affectedSourceId, Zone.BATTLEFIELD);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DESTROYED_PERMANENT:
|
case DESTROYED_PERMANENT:
|
||||||
case EXPLOITED_CREATURE:
|
case EXPLOITED_CREATURE:
|
||||||
if (isLeavesTheBattlefieldTrigger()) {
|
if (isLeavesTheBattlefieldTrigger() && game.checkShortLivingLKI(affectedSourceId, Zone.BATTLEFIELD)) {
|
||||||
source = game.getLastKnownInformation(getSourceId(), Zone.BATTLEFIELD);
|
affectedSourceObject = game.getPermanentOrLKIBattlefield(affectedSourceId);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// all other events from own object
|
return super.isInUseableZone(game, affectedSourceObject, event);
|
||||||
return super.isInUseableZone(game, source, event);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -464,23 +452,26 @@ public abstract class TriggeredAbilityImpl extends AbilityImpl implements Trigge
|
||||||
* (Similar logic must be used for any leaves-the-battlefield, but this method assumes to graveyard only.)
|
* (Similar logic must be used for any leaves-the-battlefield, but this method assumes to graveyard only.)
|
||||||
* NOTE: If your ability functions from another zone (not battlefield) then must use standard logic, not this.
|
* NOTE: If your ability functions from another zone (not battlefield) then must use standard logic, not this.
|
||||||
*/
|
*/
|
||||||
public static boolean isInUseableZoneDiesTrigger(TriggeredAbility source, GameEvent event, Game game) {
|
public static boolean isInUseableZoneDiesTrigger(TriggeredAbility sourceAbility, MageObject sourceObject, GameEvent event, Game game) {
|
||||||
// runtime check: wrong trigger settings
|
// runtime check: wrong trigger settings
|
||||||
if (!source.isLeavesTheBattlefieldTrigger()) {
|
if (!sourceAbility.isLeavesTheBattlefieldTrigger()) {
|
||||||
throw new IllegalArgumentException("Wrong code usage: all dies triggers must use setLeavesTheBattlefieldTrigger(true) and override isInUseableZone - "
|
throw new IllegalArgumentException("Wrong code usage: all dies triggers must use setLeavesTheBattlefieldTrigger(true) and override isInUseableZone - "
|
||||||
+ source.getSourceObject(game) + " - " + source);
|
+ sourceAbility.getSourceObject(game) + " - " + sourceAbility);
|
||||||
}
|
}
|
||||||
|
|
||||||
// runtime check: wrong isInUseableZone for batch related triggers
|
// runtime check: wrong isInUseableZone for batch related triggers
|
||||||
if (event instanceof BatchEvent) {
|
if (event instanceof BatchEvent) {
|
||||||
throw new IllegalArgumentException("Wrong code usage: batch events unsupported here, possible miss of override isInUseableZone - "
|
throw new IllegalArgumentException("Wrong code usage: batch events unsupported here, possible miss of override isInUseableZone - "
|
||||||
+ source.getSourceObject(game) + " - " + source);
|
+ sourceAbility.getSourceObject(game) + " - " + sourceAbility);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the source permanent of the ability
|
// workaround for singleton abilities like Flying
|
||||||
MageObject sourceObject = null;
|
UUID affectedSourceId = getRealSourceObjectId(sourceAbility, sourceObject);
|
||||||
if (game.getState().getZone(source.getSourceId()) == Zone.BATTLEFIELD) {
|
|
||||||
sourceObject = game.getPermanent(source.getSourceId());
|
// on permanent - can use actual or look back in time
|
||||||
|
MageObject affectedObject = null;
|
||||||
|
if (game.getState().getZone(affectedSourceId) == Zone.BATTLEFIELD) {
|
||||||
|
affectedObject = game.getPermanent(affectedSourceId);
|
||||||
} else {
|
} else {
|
||||||
// The idea: short living LKI must help to find a moment in the inner of resolve
|
// The idea: short living LKI must help to find a moment in the inner of resolve
|
||||||
// -
|
// -
|
||||||
|
|
@ -498,26 +489,29 @@ public abstract class TriggeredAbilityImpl extends AbilityImpl implements Trigge
|
||||||
// - ! empty stack ! graveyard ! no ! no ! no more to resolve
|
// - ! empty stack ! graveyard ! no ! no ! no more to resolve
|
||||||
// --!---------------!-------------!-----!-----------!
|
// --!---------------!-------------!-----!-----------!
|
||||||
// -
|
// -
|
||||||
if (game.checkShortLivingLKI(source.getSourceId(), Zone.BATTLEFIELD)) {
|
if (game.checkShortLivingLKI(affectedSourceId, Zone.BATTLEFIELD)) {
|
||||||
sourceObject = game.getLastKnownInformation(source.getSourceId(), Zone.BATTLEFIELD);
|
affectedObject = game.getLastKnownInformation(affectedSourceId, Zone.BATTLEFIELD);
|
||||||
}
|
|
||||||
}
|
|
||||||
if (sourceObject == null) { // source is no permanent
|
|
||||||
sourceObject = game.getObject(source);
|
|
||||||
if (sourceObject == null || sourceObject.isPermanent(game)) {
|
|
||||||
return false; // No source object found => ability is not valid
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!source.hasSourceObjectAbility(game, sourceObject, event)) {
|
if (affectedObject == null) {
|
||||||
|
affectedObject = game.getObject(sourceAbility);
|
||||||
|
if (affectedObject == null || affectedObject.isPermanent(game)) {
|
||||||
|
// if it was a permanent, but now removed then ignore
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!sourceAbility.hasSourceObjectAbility(game, affectedObject, event)) {
|
||||||
return false; // the permanent does currently not have or before it dies the ability so no trigger
|
return false; // the permanent does currently not have or before it dies the ability so no trigger
|
||||||
}
|
}
|
||||||
|
|
||||||
// check now it is in graveyard (only if it is no token and was the target itself)
|
// check now it is in graveyard (only if it is no token and was the target itself)
|
||||||
if (source.getSourceId().equals(event.getTargetId()) // source is also the target
|
// TODO: need research
|
||||||
&& !(sourceObject instanceof PermanentToken) // it's no token
|
if (affectedSourceId.equals(event.getTargetId()) // source is also the target
|
||||||
&& sourceObject.getZoneChangeCounter(game) + 1 == game.getState().getZoneChangeCounter(source.getSourceId())) { // It's in the next zone
|
&& !(affectedObject instanceof PermanentToken) // it's no token
|
||||||
Zone after = game.getState().getZone(source.getSourceId());
|
&& affectedObject.getZoneChangeCounter(game) + 1 == game.getState().getZoneChangeCounter(affectedSourceId)) { // It's in the next zone
|
||||||
|
Zone after = game.getState().getZone(affectedSourceId);
|
||||||
if (!Zone.GRAVEYARD.match(after)) { // Zone is not the graveyard
|
if (!Zone.GRAVEYARD.match(after)) { // Zone is not the graveyard
|
||||||
return false; // Moving to graveyard was replaced so no trigger
|
return false; // Moving to graveyard was replaced so no trigger
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -85,7 +85,7 @@ public class DealtDamageAndDiedTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
|
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
|
||||||
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
|
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,7 @@ public class DealtDamageAttachedAndDiedTriggeredAbility extends TriggeredAbility
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
|
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
|
||||||
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
|
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -161,7 +161,7 @@ public class DiesAttachedTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
|
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
|
||||||
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
|
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -82,11 +82,11 @@ public class DiesCreatureTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
|
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
|
||||||
if (this.zone == Zone.BATTLEFIELD) {
|
if (this.zone == Zone.BATTLEFIELD) {
|
||||||
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
|
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
|
||||||
} else {
|
} else {
|
||||||
return super.isInUseableZone(game, source, event);
|
return super.isInUseableZone(game, sourceObject, event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -56,10 +56,10 @@ public class DiesOneOrMoreTriggeredAbility extends TriggeredAbilityImpl implemen
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
|
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
|
||||||
return ((ZoneChangeBatchEvent) event)
|
return ((ZoneChangeBatchEvent) event)
|
||||||
.getEvents()
|
.getEvents()
|
||||||
.stream()
|
.stream()
|
||||||
.anyMatch(e -> TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, e, game));
|
.anyMatch(e -> TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, e, game));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ public class DiesSourceTriggeredAbility extends ZoneChangeTriggeredAbility {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
|
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
|
||||||
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
|
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,7 @@ public class DiesThisOrAnotherTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
|
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
|
||||||
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
|
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ public class PutIntoGraveFromAnywhereSourceTriggeredAbility extends ZoneChangeTr
|
||||||
// * @return
|
// * @return
|
||||||
// */
|
// */
|
||||||
// @Override
|
// @Override
|
||||||
// public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
|
// public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
|
||||||
// if (game.getState().getZone(source.getId()).equals(Zone.GRAVEYARD)) {
|
// if (game.getState().getZone(source.getId()).equals(Zone.GRAVEYARD)) {
|
||||||
// return this.hasSourceObjectAbility(game, source, event);
|
// return this.hasSourceObjectAbility(game, source, event);
|
||||||
// }
|
// }
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,7 @@ public class PutIntoGraveFromBattlefieldAllTriggeredAbility extends TriggeredAbi
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
|
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
|
||||||
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
|
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ public class PutIntoGraveFromBattlefieldSourceTriggeredAbility extends Triggered
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
|
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
|
||||||
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
|
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -107,12 +107,12 @@ public class UntilYourNextTurnDelayedTriggeredAbility extends DelayedTriggeredAb
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
|
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
|
||||||
if (isLeavesTheBattlefieldTrigger()) {
|
if (isLeavesTheBattlefieldTrigger()) {
|
||||||
// TODO: leaves battlefield and die are not same! Is it possible make a diff logic?
|
// TODO: leaves battlefield and die are not same! Is it possible make a diff logic?
|
||||||
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
|
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
|
||||||
} else {
|
} else {
|
||||||
return super.isInUseableZone(game, source, event);
|
return super.isInUseableZone(game, sourceObject, event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -137,12 +137,12 @@ public class ConditionalInterveningIfTriggeredAbility extends TriggeredAbilityIm
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
|
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
|
||||||
if (isLeavesTheBattlefieldTrigger()) {
|
if (isLeavesTheBattlefieldTrigger()) {
|
||||||
// TODO: leaves battlefield and die are not same! Is it possible make a diff logic?
|
// TODO: leaves battlefield and die are not same! Is it possible make a diff logic?
|
||||||
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
|
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
|
||||||
} else {
|
} else {
|
||||||
return super.isInUseableZone(game, source, event);
|
return super.isInUseableZone(game, sourceObject, event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -123,12 +123,12 @@ public class ConditionalTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
|
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
|
||||||
if (isLeavesTheBattlefieldTrigger()) {
|
if (isLeavesTheBattlefieldTrigger()) {
|
||||||
// TODO: leaves battlefield and die are not same! Is it possible make a diff logic?
|
// TODO: leaves battlefield and die are not same! Is it possible make a diff logic?
|
||||||
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
|
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
|
||||||
} else {
|
} else {
|
||||||
return super.isInUseableZone(game, source, event);
|
return super.isInUseableZone(game, sourceObject, event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -128,7 +128,7 @@ class HauntExileAbility extends ZoneChangeTriggeredAbility {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
|
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
|
||||||
boolean fromOK = true;
|
boolean fromOK = true;
|
||||||
Permanent sourcePermanent = (Permanent) game.getLastKnownInformation(sourceId, Zone.BATTLEFIELD);
|
Permanent sourcePermanent = (Permanent) game.getLastKnownInformation(sourceId, Zone.BATTLEFIELD);
|
||||||
if (creatureHaunt
|
if (creatureHaunt
|
||||||
|
|
|
||||||
|
|
@ -127,15 +127,15 @@ public class OrTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
|
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
|
||||||
boolean res = false;
|
boolean res = false;
|
||||||
for (TriggeredAbility ability : triggeredAbilities) {
|
for (TriggeredAbility ability : triggeredAbilities) {
|
||||||
// TODO: call full inner trigger instead like ability.isInUseableZone()?! Need research why it fails
|
// TODO: call full inner trigger instead like ability.isInUseableZone()?! Need research why it fails
|
||||||
if (ability.isLeavesTheBattlefieldTrigger()) {
|
if (ability.isLeavesTheBattlefieldTrigger()) {
|
||||||
// TODO: leaves battlefield and die are not same! Is it possible make a diff logic?
|
// TODO: leaves battlefield and die are not same! Is it possible make a diff logic?
|
||||||
res |= TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
|
res |= TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
|
||||||
} else {
|
} else {
|
||||||
res |= super.isInUseableZone(game, source, event);
|
res |= super.isInUseableZone(game, sourceObject, event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@ class MonarchDrawTriggeredAbility extends BeginningOfEndStepTriggeredAbility {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
|
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -108,7 +108,7 @@ class MonarchDealsCombatDamageToAPlayerTriggeredAbility extends TriggeredAbility
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
|
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -96,8 +96,6 @@ public class ZoneChangeEvent extends GameEvent {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Source ability of the event, can be null in rare cases
|
* Source ability of the event, can be null in rare cases
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
*/
|
||||||
public Ability getSource() {
|
public Ability getSource() {
|
||||||
return this.source;
|
return this.source;
|
||||||
|
|
@ -105,6 +103,9 @@ public class ZoneChangeEvent extends GameEvent {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return super.toString() + ", from " + getFromZone() + " to " + getToZone();
|
return super.toString()
|
||||||
|
+ ", from " + getFromZone() + " to " + getToZone()
|
||||||
|
+ ", " + (this.target == null ? "no target" : "target " + this.target)
|
||||||
|
+ ", " + (this.source == null ? "no source" : "source " + this.source);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -517,12 +517,12 @@ public class StackAbility extends StackObjectImpl implements Ability {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
|
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
|
||||||
throw new UnsupportedOperationException("Not supported.");
|
throw new UnsupportedOperationException("Not supported.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasSourceObjectAbility(Game game, MageObject source, GameEvent event) {
|
public boolean hasSourceObjectAbility(Game game, MageObject sourceObject, GameEvent event) {
|
||||||
throw new UnsupportedOperationException("Not supported.");
|
throw new UnsupportedOperationException("Not supported.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue