mirror of
https://github.com/correl/mage.git
synced 2024-11-15 11:09:30 +00:00
- Added Krovikan Vampire. Fixed Duplicity.
This commit is contained in:
parent
8485d70552
commit
ff11727596
4 changed files with 322 additions and 12 deletions
|
@ -6,10 +6,15 @@ import java.util.UUID;
|
|||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.DelayedTriggeredAbility;
|
||||
import mage.abilities.StaticAbility;
|
||||
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
|
||||
import mage.abilities.common.BeginningOfYourEndStepTriggeredAbility;
|
||||
import mage.abilities.common.EntersBattlefieldAbility;
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.abilities.effects.EntersBattlefieldEffect;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
|
||||
import mage.abilities.effects.common.discard.DiscardControllerEffect;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.CardImpl;
|
||||
|
@ -21,8 +26,8 @@ import mage.constants.TargetController;
|
|||
import mage.constants.Zone;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.events.ZoneChangeEvent;
|
||||
import mage.players.Player;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -43,7 +48,7 @@ public final class Duplicity extends CardImpl {
|
|||
this.addAbility(new BeginningOfYourEndStepTriggeredAbility(new DiscardControllerEffect(1), false));
|
||||
|
||||
// When you lose control of Duplicity, put all cards exiled with Duplicity into their owner's graveyard.
|
||||
this.addAbility(new LoseControlDuplicity());
|
||||
this.addAbility(new DuplicityEntersBattlefieldAbility(new CreateDelayedTriggeredAbilityEffect(new LoseControlDuplicity())));
|
||||
|
||||
}
|
||||
|
||||
|
@ -75,7 +80,7 @@ class DuplicityEffect extends OneShotEffect {
|
|||
if (controller != null
|
||||
&& sourceObject != null) {
|
||||
if (controller.getLibrary().hasCards()) {
|
||||
UUID exileId = CardUtil.getCardExileZoneId(game, source);
|
||||
UUID exileId = source.getSourceId();
|
||||
Set<Card> cardsToExile = controller.getLibrary().getTopCards(game, 5);
|
||||
for (Card card : cardsToExile) {
|
||||
controller.moveCardsToExile(card, source, game, true, exileId, sourceObject.getName());
|
||||
|
@ -111,7 +116,7 @@ class DuplicityExileHandEffect extends OneShotEffect {
|
|||
if (controller != null
|
||||
&& sourceObject != null) {
|
||||
if (!controller.getHand().isEmpty()) {
|
||||
UUID exileId = CardUtil.getCardExileZoneId(game, source);
|
||||
UUID exileId = source.getSourceId();
|
||||
Set<Card> cardsFromHandToExile = controller.getHand().getCards(game);
|
||||
for (Card card : cardsFromHandToExile) {
|
||||
controller.moveCardsToExile(card, source, game, true, exileId, sourceObject.getName());
|
||||
|
@ -154,12 +159,23 @@ class LoseControlDuplicity extends DelayedTriggeredAbility {
|
|||
|
||||
@Override
|
||||
public boolean checkEventType(GameEvent event, Game game) {
|
||||
return event.getType() == GameEvent.EventType.LOST_CONTROL;
|
||||
return event.getType() == GameEvent.EventType.LOST_CONTROL
|
||||
|| event.getType() == GameEvent.EventType.ZONE_CHANGE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
return event.getPlayerId().equals(controllerId);
|
||||
if (event.getType() == GameEvent.EventType.LOST_CONTROL
|
||||
&& event.getPlayerId().equals(controllerId)
|
||||
&& event.getSourceId().equals(getSourceId())) {
|
||||
return true;
|
||||
}
|
||||
if (event.getType() == GameEvent.EventType.ZONE_CHANGE
|
||||
&& event.getTargetId().equals(getSourceId())
|
||||
&& ((ZoneChangeEvent) event).getToZone() != Zone.BATTLEFIELD) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -182,14 +198,14 @@ class PutExiledCardsInOwnersGraveyard extends OneShotEffect {
|
|||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
MageObject sourceObject = game.getObject(source.getSourceId());
|
||||
if (controller != null
|
||||
&& sourceObject != null) {
|
||||
UUID exileId = CardUtil.getCardExileZoneId(game, source);
|
||||
if (controller != null) {
|
||||
UUID exileId = source.getSourceId();
|
||||
Set<Card> cardsInExile = game.getExile().getExileZone(exileId).getCards(game);
|
||||
controller.moveCardsToGraveyardWithInfo(cardsInExile, source, game, Zone.EXILED);
|
||||
if (cardsInExile != null) {
|
||||
controller.moveCards(cardsInExile, Zone.GRAVEYARD, source, game);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -198,3 +214,31 @@ class PutExiledCardsInOwnersGraveyard extends OneShotEffect {
|
|||
return new PutExiledCardsInOwnersGraveyard(this);
|
||||
}
|
||||
}
|
||||
|
||||
class DuplicityEntersBattlefieldAbility extends StaticAbility {
|
||||
|
||||
public DuplicityEntersBattlefieldAbility(Effect effect) {
|
||||
super(Zone.ALL, new EntersBattlefieldEffect(effect, null, null, true, false));
|
||||
}
|
||||
|
||||
public DuplicityEntersBattlefieldAbility(final DuplicityEntersBattlefieldAbility ability) {
|
||||
super(ability);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addEffect(Effect effect) {
|
||||
if (!getEffects().isEmpty()) {
|
||||
Effect entersBattlefieldEffect = this.getEffects().get(0);
|
||||
if (entersBattlefieldEffect instanceof EntersBattlefieldEffect) {
|
||||
((EntersBattlefieldEffect) entersBattlefieldEffect).addEffect(effect);
|
||||
return;
|
||||
}
|
||||
}
|
||||
super.addEffect(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DuplicityEntersBattlefieldAbility copy() {
|
||||
return new DuplicityEntersBattlefieldAbility(this);
|
||||
}
|
||||
}
|
||||
|
|
264
Mage.Sets/src/mage/cards/k/KrovikanVampire.java
Normal file
264
Mage.Sets/src/mage/cards/k/KrovikanVampire.java
Normal file
|
@ -0,0 +1,264 @@
|
|||
package mage.cards.k;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.DelayedTriggeredAbility;
|
||||
import mage.abilities.common.BeginningOfEndStepTriggeredAbility;
|
||||
import mage.abilities.condition.Condition;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.SacrificeTargetEffect;
|
||||
import mage.constants.SubType;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.TargetController;
|
||||
import mage.constants.WatcherScope;
|
||||
import mage.constants.Zone;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.events.GameEvent.EventType;
|
||||
import mage.game.events.ZoneChangeEvent;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Player;
|
||||
import mage.target.targetpointer.FixedTarget;
|
||||
import mage.watchers.Watcher;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author jeffwadsworth
|
||||
*/
|
||||
public final class KrovikanVampire extends CardImpl {
|
||||
|
||||
public KrovikanVampire(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}{B}");
|
||||
|
||||
this.subtype.add(SubType.VAMPIRE);
|
||||
this.power = new MageInt(3);
|
||||
this.toughness = new MageInt(3);
|
||||
|
||||
// At the beginning of each end step, if a creature dealt damage by Krovikan Vampire this turn died, put that card onto the battlefield under your control. Sacrifice it when you lose control of Krovikan Vampire.
|
||||
Ability ability = new BeginningOfEndStepTriggeredAbility(
|
||||
Zone.BATTLEFIELD,
|
||||
new KrovikanVampireEffect(),
|
||||
TargetController.ANY,
|
||||
KrovikanVampireInterveningIfCondition.instance,
|
||||
false);
|
||||
ability.addWatcher(new KrovikanVampireCreaturesDamagedWatcher());
|
||||
ability.addWatcher(new KrovikanVampireCreaturesDiedWatcher());
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
||||
public KrovikanVampire(final KrovikanVampire card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public KrovikanVampire copy() {
|
||||
return new KrovikanVampire(this);
|
||||
}
|
||||
}
|
||||
|
||||
class KrovikanVampireEffect extends OneShotEffect {
|
||||
|
||||
Set<UUID> creaturesAffected = new HashSet<>();
|
||||
|
||||
KrovikanVampireEffect() {
|
||||
super(Outcome.Neutral);
|
||||
staticText = "put that card onto the battlefield under your control. Sacrifice it when you lose control of {this}";
|
||||
}
|
||||
|
||||
KrovikanVampireEffect(KrovikanVampireEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
Permanent krovikanVampire = game.getPermanent(source.getSourceId());
|
||||
creaturesAffected = (Set<UUID>) game.getState().getValue(source.getSourceId() + "creatureToGainControl");
|
||||
if (creaturesAffected != null
|
||||
&& controller != null
|
||||
&& krovikanVampire != null) {
|
||||
for (UUID creatureId : creaturesAffected) {
|
||||
controller.moveCards(game.getCard(creatureId), Zone.BATTLEFIELD, source, game, false, false, false, null);
|
||||
OneShotEffect effect = new SacrificeTargetEffect();
|
||||
effect.setText("Sacrifice this if Krovikan Vampire leaves the battlefield or its current controller loses control of it.");
|
||||
effect.setTargetPointer(new FixedTarget(creatureId));
|
||||
KrovikanVampireDelayedTriggeredAbility dTA = new KrovikanVampireDelayedTriggeredAbility(effect, krovikanVampire.getId());
|
||||
game.addDelayedTriggeredAbility(dTA, source);
|
||||
}
|
||||
creaturesAffected.clear();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public KrovikanVampireEffect copy() {
|
||||
return new KrovikanVampireEffect(this);
|
||||
}
|
||||
}
|
||||
|
||||
enum KrovikanVampireInterveningIfCondition implements Condition {
|
||||
|
||||
instance;
|
||||
Set<UUID> creaturesAffected = new HashSet<>();
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
KrovikanVampireCreaturesDiedWatcher watcherDied = (KrovikanVampireCreaturesDiedWatcher) game.getState().getWatchers().get(KrovikanVampireCreaturesDiedWatcher.class.getSimpleName());
|
||||
KrovikanVampireCreaturesDamagedWatcher watcherDamaged = (KrovikanVampireCreaturesDamagedWatcher) game.getState().getWatchers().get(KrovikanVampireCreaturesDamagedWatcher.class.getSimpleName());
|
||||
if (watcherDied != null) {
|
||||
Set<UUID> creaturesThatDiedThisTurn = watcherDied.diedThisTurn;
|
||||
if (creaturesThatDiedThisTurn != null) {
|
||||
for (UUID mor : creaturesThatDiedThisTurn) {
|
||||
if (watcherDamaged != null) {
|
||||
for (UUID mor2 : watcherDamaged.getDamagedBySource()) {
|
||||
if (mor2 != null
|
||||
&& mor == mor2) {
|
||||
creaturesAffected.add(mor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (creaturesAffected != null
|
||||
&& creaturesAffected.size() > 0) {
|
||||
game.getState().setValue(source.getSourceId() + "creatureToGainControl", creaturesAffected);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "if a creature dealt damage by Krovikan Vampire this turn died";
|
||||
}
|
||||
}
|
||||
|
||||
class KrovikanVampireCreaturesDamagedWatcher extends Watcher {
|
||||
|
||||
public final Set<UUID> damagedBySource = new HashSet<>();
|
||||
|
||||
public KrovikanVampireCreaturesDamagedWatcher() {
|
||||
super(KrovikanVampireCreaturesDamagedWatcher.class.getSimpleName(), WatcherScope.GAME);
|
||||
}
|
||||
|
||||
public KrovikanVampireCreaturesDamagedWatcher(final KrovikanVampireCreaturesDamagedWatcher watcher) {
|
||||
super(watcher);
|
||||
this.damagedBySource.addAll(watcher.damagedBySource);
|
||||
}
|
||||
|
||||
@Override
|
||||
public KrovikanVampireCreaturesDamagedWatcher copy() {
|
||||
return new KrovikanVampireCreaturesDamagedWatcher(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void watch(GameEvent event, Game game) {
|
||||
if (event.getType() == EventType.DAMAGED_CREATURE
|
||||
&& sourceId.equals(event.getSourceId())) {
|
||||
damagedBySource.add(event.getTargetId());
|
||||
}
|
||||
}
|
||||
|
||||
public Set<UUID> getDamagedBySource() {
|
||||
return this.damagedBySource;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
damagedBySource.clear();
|
||||
}
|
||||
}
|
||||
|
||||
class KrovikanVampireCreaturesDiedWatcher extends Watcher {
|
||||
|
||||
public final Set<UUID> diedThisTurn = new HashSet<>();
|
||||
|
||||
public KrovikanVampireCreaturesDiedWatcher() {
|
||||
super(KrovikanVampireCreaturesDiedWatcher.class.getSimpleName(), WatcherScope.GAME);
|
||||
}
|
||||
|
||||
public KrovikanVampireCreaturesDiedWatcher(final KrovikanVampireCreaturesDiedWatcher watcher) {
|
||||
super(watcher);
|
||||
this.diedThisTurn.addAll(watcher.diedThisTurn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void watch(GameEvent event, Game game) {
|
||||
if (event.getType() == GameEvent.EventType.ZONE_CHANGE) {
|
||||
ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
|
||||
if (zEvent.isDiesEvent()
|
||||
&& zEvent.getTarget() != null
|
||||
&& zEvent.getTarget().isCreature()) {
|
||||
diedThisTurn.add(zEvent.getTargetId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
diedThisTurn.clear();
|
||||
}
|
||||
|
||||
public Set<UUID> getDiedThisTurn() {
|
||||
return this.diedThisTurn;
|
||||
}
|
||||
|
||||
@Override
|
||||
public KrovikanVampireCreaturesDiedWatcher copy() {
|
||||
return new KrovikanVampireCreaturesDiedWatcher(this);
|
||||
}
|
||||
}
|
||||
|
||||
class KrovikanVampireDelayedTriggeredAbility extends DelayedTriggeredAbility {
|
||||
|
||||
UUID krovikanVampire;
|
||||
|
||||
KrovikanVampireDelayedTriggeredAbility(Effect effect, UUID krovikanVampire) {
|
||||
super(effect, Duration.EndOfGame, true);
|
||||
this.krovikanVampire = krovikanVampire;
|
||||
}
|
||||
|
||||
KrovikanVampireDelayedTriggeredAbility(KrovikanVampireDelayedTriggeredAbility ability) {
|
||||
super(ability);
|
||||
this.krovikanVampire = ability.krovikanVampire;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkEventType(GameEvent event, Game game) {
|
||||
return event.getType() == EventType.LOST_CONTROL
|
||||
|| event.getType() == EventType.ZONE_CHANGE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
if (event.getType() == EventType.LOST_CONTROL
|
||||
&& event.getSourceId().equals(krovikanVampire)) {
|
||||
return true;
|
||||
}
|
||||
if (event.getType() == EventType.ZONE_CHANGE
|
||||
&& event.getTargetId().equals(krovikanVampire)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public KrovikanVampireDelayedTriggeredAbility copy() {
|
||||
return new KrovikanVampireDelayedTriggeredAbility(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRule() {
|
||||
return "LOSE CONTROL DUDE WORKS";
|
||||
}
|
||||
}
|
|
@ -195,6 +195,7 @@ public final class IceAge extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Krovikan Elementalist", 139, Rarity.UNCOMMON, mage.cards.k.KrovikanElementalist.class));
|
||||
cards.add(new SetCardInfo("Krovikan Fetish", 140, Rarity.COMMON, mage.cards.k.KrovikanFetish.class));
|
||||
cards.add(new SetCardInfo("Krovikan Sorcerer", 81, Rarity.COMMON, mage.cards.k.KrovikanSorcerer.class));
|
||||
cards.add(new SetCardInfo("Krovikan Vampire", 29, Rarity.UNCOMMON, mage.cards.k.KrovikanVampire.class));
|
||||
cards.add(new SetCardInfo("Land Cap", 357, Rarity.RARE, mage.cards.l.LandCap.class));
|
||||
cards.add(new SetCardInfo("Lapis Lazuli Talisman", 327, Rarity.UNCOMMON, mage.cards.l.LapisLazuliTalisman.class));
|
||||
cards.add(new SetCardInfo("Lava Tubes", 358, Rarity.RARE, mage.cards.l.LavaTubes.class));
|
||||
|
|
|
@ -147,6 +147,7 @@ public final class MastersEditionII extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Krovikan Fetish", 100, Rarity.COMMON, mage.cards.k.KrovikanFetish.class));
|
||||
cards.add(new SetCardInfo("Krovikan Horror", 101, Rarity.RARE, mage.cards.k.KrovikanHorror.class));
|
||||
cards.add(new SetCardInfo("Krovikan Sorcerer", 51, Rarity.COMMON, mage.cards.k.KrovikanSorcerer.class));
|
||||
cards.add(new SetCardInfo("Krovikan Vampire", 102, Rarity.UNCOMMON, mage.cards.k.KrovikanVampire.class));
|
||||
cards.add(new SetCardInfo("Lat-Nam's Legacy", 52, Rarity.COMMON, mage.cards.l.LatNamsLegacy.class));
|
||||
cards.add(new SetCardInfo("Leaping Lizard", 171, Rarity.COMMON, mage.cards.l.LeapingLizard.class));
|
||||
cards.add(new SetCardInfo("Lim-Dul's High Guard", 103, Rarity.UNCOMMON, mage.cards.l.LimDulsHighGuard.class));
|
||||
|
|
Loading…
Reference in a new issue