refactor: shared logic for diff implementation of isInUseableZone, improved docs and readability;

This commit is contained in:
Oleg Agafonov 2024-11-30 03:26:03 +04:00
parent 57ef74da90
commit d49ff89a81
76 changed files with 285 additions and 273 deletions

View file

@ -103,7 +103,7 @@ class AjanisLastStandTriggeredAbility extends TriggeredAbilityImpl {
}
@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
}

View file

@ -157,7 +157,7 @@ class AthreosDiesCreatureTriggeredAbility extends TriggeredAbilityImpl {
}
@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
}

View file

@ -95,7 +95,7 @@ class AvacynsCollarTriggeredAbility extends TriggeredAbilityImpl {
}
@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
}

View file

@ -78,7 +78,7 @@ class BereavementTriggeredAbility extends TriggeredAbilityImpl {
}
@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
}

View file

@ -95,7 +95,7 @@ class DeathTyrantTriggeredAbility extends TriggeredAbilityImpl {
}
@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
}

View file

@ -82,7 +82,7 @@ class DeathsPresenceTriggeredAbility extends TriggeredAbilityImpl {
}
@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
}

View file

@ -103,7 +103,7 @@ class DiregrafCaptainTriggeredAbility extends TriggeredAbilityImpl {
}
@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
}

View file

@ -92,7 +92,7 @@ class FalkenrathNobleTriggeredAbility extends TriggeredAbilityImpl {
}
@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
}

View file

@ -97,8 +97,8 @@ class GraveBetrayalTriggeredAbility extends TriggeredAbilityImpl {
}
@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
}

View file

@ -77,8 +77,8 @@ class GravePactTriggeredAbility extends TriggeredAbilityImpl {
}
@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
}

View file

@ -86,8 +86,8 @@ class GutterGrimeTriggeredAbility extends TriggeredAbilityImpl {
}
@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
}

View file

@ -109,7 +109,7 @@ class HatefulEidolonTriggeredAbility extends TriggeredAbilityImpl {
}
@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
}

View file

@ -94,7 +94,7 @@ class InfestedThrinaxTriggeredAbility extends DelayedTriggeredAbility {
}
@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
}

View file

@ -101,8 +101,8 @@ class LuminousBroodmothTriggeredAbility extends TriggeredAbilityImpl {
}
@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
}

View file

@ -103,8 +103,8 @@ class LyndeCheerfulTormentorCurseDiesTriggeredAbility extends TriggeredAbilityIm
}
@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
@Override

View file

@ -104,8 +104,8 @@ class MarchesaTheBlackRoseTriggeredAbility extends TriggeredAbilityImpl {
}
@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
}

View file

@ -206,8 +206,8 @@ class MariTheKillingQuillCreatureDiesAbility extends TriggeredAbilityImpl {
}
@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
}

View file

@ -91,8 +91,8 @@ class MartyrsBondTriggeredAbility extends TriggeredAbilityImpl {
}
@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
}

View file

@ -108,7 +108,7 @@ class MassacreGirlDelayedTriggeredAbility extends DelayedTriggeredAbility {
}
@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
}

View file

@ -85,7 +85,7 @@ class MassacreWurmTriggeredAbility extends TriggeredAbilityImpl {
}
@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
}

View file

@ -125,11 +125,11 @@ class MillicentRestlessRevenantTriggeredAbility extends TriggeredAbilityImpl {
}
@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) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
} else {
return super.isInUseableZone(game, source, event);
return super.isInUseableZone(game, sourceObject, event);
}
}

View file

@ -110,8 +110,8 @@ class MimicVatTriggeredAbility extends TriggeredAbilityImpl {
}
@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
}

View file

@ -78,7 +78,7 @@ class MolderBeastTriggeredAbility extends TriggeredAbilityImpl {
}
@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
}

View file

@ -94,7 +94,7 @@ class MycoidShepherdTriggeredAbility extends TriggeredAbilityImpl {
}
@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
}

View file

@ -96,7 +96,7 @@ class NecroskitterTriggeredAbility extends TriggeredAbilityImpl {
}
@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
}

View file

@ -98,7 +98,7 @@ class NetherTraitorTriggeredAbility extends TriggeredAbilityImpl {
}
@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
}

View file

@ -112,8 +112,8 @@ class NimDeathmantleTriggeredAbility extends TriggeredAbilityImpl {
}
@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
}

View file

@ -98,7 +98,7 @@ class OrahSkyclaveHierophantTriggeredAbility extends TriggeredAbilityImpl {
}
@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
}

View file

@ -110,8 +110,8 @@ class PatronOfTheVeinCreatureDiesTriggeredAbility extends TriggeredAbilityImpl {
}
@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
}

View file

@ -131,7 +131,7 @@ class PiasRevolutionTriggeredAbility extends TriggeredAbilityImpl {
}
@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
}

View file

@ -80,7 +80,7 @@ class ProperBurialTriggeredAbility extends TriggeredAbilityImpl {
}
@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
}

View file

@ -106,8 +106,8 @@ class PurgatoryTriggeredAbility extends TriggeredAbilityImpl {
}
@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
}

View file

@ -96,7 +96,7 @@ class RemembranceTriggeredAbility extends TriggeredAbilityImpl {
}
@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
}

View file

@ -114,11 +114,11 @@ class RhukHexgoldNabberTriggeredAbility extends TriggeredAbilityImpl {
}
@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) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
} else {
return super.isInUseableZone(game, source, event);
return super.isInUseableZone(game, sourceObject, event);
}
}
}

View file

@ -113,8 +113,8 @@ class RienneAngelOfRebirthTriggeredAbility extends TriggeredAbilityImpl {
}
@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
}

View file

@ -79,7 +79,7 @@ class SacredGroundTriggeredAbility extends TriggeredAbilityImpl {
}
@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
}

View file

@ -80,8 +80,8 @@ class SangromancerFirstTriggeredAbility extends TriggeredAbilityImpl {
}
@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
}

View file

@ -94,7 +94,7 @@ class ScrapTrawlerTriggeredAbility extends TriggeredAbilityImpl {
}
@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
}

View file

@ -80,7 +80,7 @@ class ScrapheapTriggeredAbility extends TriggeredAbilityImpl {
}
@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
}

View file

@ -89,7 +89,7 @@ class SeerOfStolenSightTriggeredAbility extends TriggeredAbilityImpl {
}
@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
}

View file

@ -189,8 +189,8 @@ class ShelobChildOfUngoliantTriggeredAbility extends TriggeredAbilityImpl {
}
@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
}

View file

@ -83,7 +83,7 @@ class SlagstoneRefineryTriggeredAbility extends TriggeredAbilityImpl {
}
@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
}

View file

@ -92,7 +92,7 @@ class SlayersPlateTriggeredAbility extends TriggeredAbilityImpl {
}
@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
}

View file

@ -108,8 +108,8 @@ class SporogenesisTriggeredAbility extends TriggeredAbilityImpl {
}
@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
}

View file

@ -96,8 +96,8 @@ class SyrKonradTheGrimTriggeredAbility extends TriggeredAbilityImpl {
}
@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
@Override

View file

@ -109,8 +109,8 @@ class TheScorpionGodTriggeredAbility extends TriggeredAbilityImpl {
}
@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
}

View file

@ -171,8 +171,8 @@ class TheSkullsporeNexusTrigger extends TriggeredAbilityImpl {
}
@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
}

View file

@ -102,8 +102,8 @@ class TianaShipsCaretakerTriggeredAbility extends TriggeredAbilityImpl {
}
@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
}

View file

@ -101,8 +101,8 @@ class VerdantSuccessionTriggeredAbility extends TriggeredAbilityImpl {
}
@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
}

View file

@ -78,7 +78,7 @@ class VillageCannibalsTriggeredAbility extends TriggeredAbilityImpl {
}
@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
}

View file

@ -70,8 +70,8 @@ class VindictiveVampireTriggeredAbility extends TriggeredAbilityImpl {
}
@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
@Override

View file

@ -81,7 +81,7 @@ class ViridianRevelTriggeredAbility extends TriggeredAbilityImpl {
}
@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
}

View file

@ -105,7 +105,7 @@ class XiraTheGoldenStingTriggeredAbility extends WhenTargetDiesDelayedTriggeredA
}
@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
}

View file

@ -86,9 +86,6 @@ public interface Ability extends Controllable, Serializable {
* Gets the id of the object which put this ability in motion.
* <p>
* 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();
@ -358,16 +355,17 @@ public interface Ability extends Controllable, Serializable {
* - for leave battlefield triggers - keep default + 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
* object can have lost all or some abilities for some time (e.g. Turn to
* 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
@ -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.
* Warning, do not use with singleton abilities
*/
MageObject getSourceObject(Game game);

View file

@ -1175,35 +1175,31 @@ public abstract class AbilityImpl implements Ability {
}
@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
if (!this.hasSourceObjectAbility(game, source, event)) {
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
if (!this.hasSourceObjectAbility(game, sourceObject, event)) {
return false;
}
// workaround for singleton abilities like Flying
UUID affectedSourceId = getRealSourceObjectId(this, sourceObject);
// in command zone
if (zone == Zone.COMMAND) {
if (this.getSourceId() == null) { // commander effects
if (affectedSourceId == null) {
// commander effects
return true;
} else {
MageObject object = game.getObject(affectedSourceId);
// emblem/planes are always actual
if (object instanceof Emblem || object instanceof Dungeon || object instanceof Plane) {
return true;
}
}
MageObject object = game.getObject(this.getSourceId());
// emblem/planes are always actual
if (object instanceof Emblem || object instanceof Dungeon || object instanceof Plane) {
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
// 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;
}
@ -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
// 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.
// ...
@ -1228,12 +1224,12 @@ public abstract class AbilityImpl implements Ability {
// TODO: research "put into a hand or library"
if (isTriggerCanFireAfterLeaveBattlefield(event)) {
// permanents with normal triggers
if (source instanceof Permanent) {
if (sourceObject instanceof Permanent) { // TODO: use affectedSourceObject here?
// support leaves-the-battlefield abilities
sourceObjectZone = Zone.BATTLEFIELD;
}
// 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;
}
}
@ -1267,6 +1263,7 @@ public abstract class AbilityImpl implements Ability {
// need research: is it ability's or event's task?
// - ability's task: code like ability.setLookBackInTime
// - event's task: code like current switch
// TODO: alternative solution: replace check by source.isLeavesTheBattlefieldTrigger?
switch (e.getType()) {
case DESTROYED_PERMANENT:
case EXPLOITED_CREATURE:
@ -1279,31 +1276,43 @@ public abstract class AbilityImpl implements Ability {
});
}
@Override
public boolean hasSourceObjectAbility(Game game, MageObject source, GameEvent event) {
// if source object have this ability
// uses for ability.isInUseableZone
// replacement and other continues effects can be without source, but active (must return true)
MageObject object = source;
// for singleton abilities like Flying we can't rely on abilities' source because it's only once in continuous effects
/**
* Find real source object id from any ability (real and singleton)
*/
protected static UUID getRealSourceObjectId(Ability sourceAbility, MageObject sourceObject) {
// In singleton abilities like Flying we can't rely on ability's source because it's init 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 (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) {
object = game.getPermanentEntering(getSourceId());
if (object == null) {
object = game.getObject(getSourceId());
}
}
if (object != null) {
if (object instanceof Permanent) {
return object.hasAbility(this, game) && (
((Permanent) object).isPhasedIn() || this.getWorksPhasedOut()
);
} else {
// cards and other objects
return object.hasAbility(this, game);
}
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) {
return ((Permanent) object).isPhasedIn() || this.getWorksPhasedOut();
}
return true;
}

View file

@ -209,7 +209,7 @@ public class TriggeredAbilities extends LinkedHashMap<String, TriggeredAbility>
if (ability.isInUseableZone(game, object, event)) {
if (event == null || !game.getContinuousEffects().preventedByRuleModification(event, ability, game, false)) {
if (object != null) {
boolean controllerSet = false;
boolean controllerSet = false; // TODO: wtf?!?!? Need rework whole "set" logic here
Set<UUID> eventTargets = CardUtil.getEventTargets(event);
if (ability.getZone() != Zone.COMMAND
&& event != null

View file

@ -72,6 +72,15 @@ public interface TriggeredAbility extends Ability {
* 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
* 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 arent 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);

View file

@ -348,73 +348,61 @@ public abstract class TriggeredAbilityImpl extends AbilityImpl implements Trigge
}
@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
/**
* 603.6. Trigger events that involve objects changing zones are called
* 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.
*/
// workaround for singleton abilities like Flying
UUID affectedSourceId = getRealSourceObjectId(this, sourceObject);
// process events from other objects
Set<UUID> eventTargets = CardUtil.getEventTargets(event);
if (!eventTargets.contains(getSourceId())) {
return super.isInUseableZone(game, source, event);
}
// 603.6
// Trigger events that involve objects changing zones are called "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 opponents 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 code with AbilityImpl.isInUseableZone
switch (event.getType()) {
case ZONE_CHANGE:
ZoneChangeEvent zce = (ZoneChangeEvent) event;
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.
if (zce.getFromZone().match(Zone.GRAVEYARD)) {
if (!CardUtil.cardHadAbility(this, game.getLastKnownInformationCard(getSourceId(), zce.getFromZone()), getSourceId(), game)) {
return false;
// TODO: need sync or shared 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()) {
case ZONE_CHANGE:
ZoneChangeEvent zce = (ZoneChangeEvent) event;
Set<UUID> eventTargets = CardUtil.getEventTargets(event);
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,
// that ability triggers from the graveyard, (such as Golgari Brownscale),
// Yixlid Jailer will prevent that ability from triggering.
if (zce.getFromZone().match(Zone.GRAVEYARD)) {
if (!CardUtil.cardHadAbility(this, game.getLastKnownInformationCard(getSourceId(), zce.getFromZone()), getSourceId(), game)) {
return false;
}
}
}
}
if (isLeavesTheBattlefieldTrigger()) {
source = zce.getTarget();
}
break;
case DESTROYED_PERMANENT:
case EXPLOITED_CREATURE:
if (isLeavesTheBattlefieldTrigger()) {
source = game.getLastKnownInformation(getSourceId(), Zone.BATTLEFIELD);
}
break;
if (isLeavesTheBattlefieldTrigger() && game.checkShortLivingLKI(affectedSourceId, Zone.BATTLEFIELD)) {
affectedSourceObject = game.getLastKnownInformation(affectedSourceId, Zone.BATTLEFIELD);
}
break;
case DESTROYED_PERMANENT:
case EXPLOITED_CREATURE:
if (isLeavesTheBattlefieldTrigger() && game.checkShortLivingLKI(affectedSourceId, Zone.BATTLEFIELD)) {
affectedSourceObject = game.getPermanentOrLKIBattlefield(affectedSourceId);
}
break;
}
}
// all other events from own object
return super.isInUseableZone(game, source, event);
return super.isInUseableZone(game, affectedSourceObject, event);
}
@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.)
* 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
if (!source.isLeavesTheBattlefieldTrigger()) {
if (!sourceAbility.isLeavesTheBattlefieldTrigger()) {
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
if (event instanceof BatchEvent) {
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
MageObject sourceObject = null;
if (game.getState().getZone(source.getSourceId()) == Zone.BATTLEFIELD) {
sourceObject = game.getPermanent(source.getSourceId());
// workaround for singleton abilities like Flying
UUID affectedSourceId = getRealSourceObjectId(sourceAbility, sourceObject);
// 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 {
// 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
// --!---------------!-------------!-----!-----------!
// -
if (game.checkShortLivingLKI(source.getSourceId(), Zone.BATTLEFIELD)) {
sourceObject = game.getLastKnownInformation(source.getSourceId(), 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 (game.checkShortLivingLKI(affectedSourceId, Zone.BATTLEFIELD)) {
affectedObject = game.getLastKnownInformation(affectedSourceId, Zone.BATTLEFIELD);
}
}
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
}
// 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
&& !(sourceObject instanceof PermanentToken) // it's no token
&& sourceObject.getZoneChangeCounter(game) + 1 == game.getState().getZoneChangeCounter(source.getSourceId())) { // It's in the next zone
Zone after = game.getState().getZone(source.getSourceId());
// TODO: need research
if (affectedSourceId.equals(event.getTargetId()) // source is also the target
&& !(affectedObject instanceof PermanentToken) // it's no token
&& 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
return false; // Moving to graveyard was replaced so no trigger
}

View file

@ -85,7 +85,7 @@ public class DealtDamageAndDiedTriggeredAbility extends TriggeredAbilityImpl {
}
@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
}

View file

@ -79,7 +79,7 @@ public class DealtDamageAttachedAndDiedTriggeredAbility extends TriggeredAbility
}
@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
}

View file

@ -161,7 +161,7 @@ public class DiesAttachedTriggeredAbility extends TriggeredAbilityImpl {
}
@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
}

View file

@ -82,11 +82,11 @@ public class DiesCreatureTriggeredAbility extends TriggeredAbilityImpl {
}
@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
if (this.zone == Zone.BATTLEFIELD) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
} else {
return super.isInUseableZone(game, source, event);
return super.isInUseableZone(game, sourceObject, event);
}
}
}

View file

@ -56,10 +56,10 @@ public class DiesOneOrMoreTriggeredAbility extends TriggeredAbilityImpl implemen
}
@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return ((ZoneChangeBatchEvent) event)
.getEvents()
.stream()
.anyMatch(e -> TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, e, game));
.anyMatch(e -> TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, e, game));
}
}

View file

@ -42,7 +42,7 @@ public class DiesSourceTriggeredAbility extends ZoneChangeTriggeredAbility {
}
@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
}

View file

@ -66,7 +66,7 @@ public class DiesThisOrAnotherTriggeredAbility extends TriggeredAbilityImpl {
}
@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
}

View file

@ -41,7 +41,7 @@ public class PutIntoGraveFromAnywhereSourceTriggeredAbility extends ZoneChangeTr
// * @return
// */
// @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)) {
// return this.hasSourceObjectAbility(game, source, event);
// }

View file

@ -66,7 +66,7 @@ public class PutIntoGraveFromBattlefieldAllTriggeredAbility extends TriggeredAbi
}
@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
}

View file

@ -58,7 +58,7 @@ public class PutIntoGraveFromBattlefieldSourceTriggeredAbility extends Triggered
}
@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, event, game);
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game);
}
}

View file

@ -107,12 +107,12 @@ public class UntilYourNextTurnDelayedTriggeredAbility extends DelayedTriggeredAb
}
@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
if (isLeavesTheBattlefieldTrigger()) {
// 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 {
return super.isInUseableZone(game, source, event);
return super.isInUseableZone(game, sourceObject, event);
}
}
}

View file

@ -137,12 +137,12 @@ public class ConditionalInterveningIfTriggeredAbility extends TriggeredAbilityIm
}
@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
if (isLeavesTheBattlefieldTrigger()) {
// 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 {
return super.isInUseableZone(game, source, event);
return super.isInUseableZone(game, sourceObject, event);
}
}
}

View file

@ -123,12 +123,12 @@ public class ConditionalTriggeredAbility extends TriggeredAbilityImpl {
}
@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
if (isLeavesTheBattlefieldTrigger()) {
// 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 {
return super.isInUseableZone(game, source, event);
return super.isInUseableZone(game, sourceObject, event);
}
}
}

View file

@ -128,7 +128,7 @@ class HauntExileAbility extends ZoneChangeTriggeredAbility {
}
@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
boolean fromOK = true;
Permanent sourcePermanent = (Permanent) game.getLastKnownInformation(sourceId, Zone.BATTLEFIELD);
if (creatureHaunt

View file

@ -127,15 +127,15 @@ public class OrTriggeredAbility extends TriggeredAbilityImpl {
}
@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
boolean res = false;
for (TriggeredAbility ability : triggeredAbilities) {
// TODO: call full inner trigger instead like ability.isInUseableZone()?! Need research why it fails
if (ability.isLeavesTheBattlefieldTrigger()) {
// 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 {
res |= super.isInUseableZone(game, source, event);
res |= super.isInUseableZone(game, sourceObject, event);
}
}
return res;

View file

@ -61,7 +61,7 @@ class MonarchDrawTriggeredAbility extends BeginningOfEndStepTriggeredAbility {
}
@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return true;
}
@ -108,7 +108,7 @@ class MonarchDealsCombatDamageToAPlayerTriggeredAbility extends TriggeredAbility
}
@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
return true;
}

View file

@ -96,8 +96,6 @@ public class ZoneChangeEvent extends GameEvent {
/**
* Source ability of the event, can be null in rare cases
*
* @return
*/
public Ability getSource() {
return this.source;
@ -105,6 +103,9 @@ public class ZoneChangeEvent extends GameEvent {
@Override
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);
}
}

View file

@ -517,12 +517,12 @@ public class StackAbility extends StackObjectImpl implements Ability {
}
@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) {
throw new UnsupportedOperationException("Not supported.");
}
@Override
public boolean hasSourceObjectAbility(Game game, MageObject source, GameEvent event) {
public boolean hasSourceObjectAbility(Game game, MageObject sourceObject, GameEvent event) {
throw new UnsupportedOperationException("Not supported.");
}