updated implementation of equipment which use themself in a gained ability

This commit is contained in:
Evan Kranzler 2020-10-22 21:37:03 -04:00
parent 26ba64852f
commit a66428b2b6
13 changed files with 534 additions and 390 deletions

View file

@ -1,15 +1,14 @@
package mage.cards.b;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.Mode;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.costs.Cost;
import mage.abilities.costs.CostImpl;
import mage.abilities.costs.common.SacrificeAttachmentCost;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.combat.CantBeBlockedByCreaturesAttachedEffect;
import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect;
import mage.abilities.effects.common.continuous.GainAbilityWithAttachmentEffect;
import mage.abilities.keyword.EquipAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
@ -21,7 +20,6 @@ import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetAnyTarget;
import java.util.List;
import java.util.UUID;
/**
@ -32,8 +30,10 @@ public final class BlazingTorch extends CardImpl {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Vampires or Zombies");
static {
filter.add(Predicates.or(SubType.VAMPIRE.getPredicate(),
SubType.ZOMBIE.getPredicate()));
filter.add(Predicates.or(
SubType.VAMPIRE.getPredicate(),
SubType.ZOMBIE.getPredicate()
));
}
public BlazingTorch(UUID ownerId, CardSetInfo setInfo) {
@ -41,15 +41,15 @@ public final class BlazingTorch extends CardImpl {
this.subtype.add(SubType.EQUIPMENT);
// Equipped creature can't be blocked by Vampires or Zombies. (!this is a static ability of the equipment)
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD,
new CantBeBlockedByCreaturesAttachedEffect(Duration.WhileOnBattlefield, filter, AttachmentType.EQUIPMENT)));
this.addAbility(new SimpleStaticAbility(new CantBeBlockedByCreaturesAttachedEffect(
Duration.WhileOnBattlefield, filter, AttachmentType.EQUIPMENT
)));
// Equipped creature has "{tap}, Sacrifice Blazing Torch: Blazing Torch deals 2 damage to any target.")
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BlazingTorchDamageEffect(), new TapSourceCost());
ability.addCost(new BlazingTorchCost());
ability.addTarget(new TargetAnyTarget());
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(ability, AttachmentType.EQUIPMENT)));
// Equipped creature has "{tap}, Sacrifice Blazing Torch: Blazing Torch deals 2 damage to any target."
this.addAbility(new SimpleStaticAbility(new GainAbilityWithAttachmentEffect(
"equipped creature has \"{tap}, Sacrifice {this}: {this} deals 2 damage to any target.\"",
new BlazingTorchEffect(), new TargetAnyTarget(), new SacrificeAttachmentCost(), new TapSourceCost()
)));
// Equip {1}
this.addAbility(new EquipAbility(Outcome.BoostCreature, new GenericManaCost(1)));
@ -65,76 +65,48 @@ public final class BlazingTorch extends CardImpl {
}
}
class BlazingTorchCost extends CostImpl {
class BlazingTorchEffect extends OneShotEffect {
public BlazingTorchCost() {
this.text = "Sacrifice Blazing Torch";
BlazingTorchEffect() {
super(Outcome.Benefit);
}
public BlazingTorchCost(BlazingTorchCost cost) {
super(cost);
}
@Override
public boolean pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana, Cost costToPay) {
Permanent permanent = game.getPermanent(ability.getSourceId());
List<UUID> attachments = permanent.getAttachments();
for (UUID attachmentId : attachments) {
Permanent attachment = game.getPermanent(attachmentId);
if (attachment != null && attachment.getName().equals("Blazing Torch")) {
((BlazingTorchDamageEffect) ability.getEffects().get(0)).setSourceId(attachmentId);
paid |= attachment.sacrifice(sourceId, game);
return paid;
}
}
return paid;
}
@Override
public boolean canPay(Ability ability, UUID sourceId, UUID controllerId, Game game) {
return true;
}
@Override
public BlazingTorchCost copy() {
return new BlazingTorchCost(this);
}
}
class BlazingTorchDamageEffect extends OneShotEffect {
private UUID sourceId;
public BlazingTorchDamageEffect() {
super(Outcome.Damage);
this.staticText = "Blazing Torch deals 2 damage to any target";
}
public BlazingTorchDamageEffect(final BlazingTorchDamageEffect effect) {
private BlazingTorchEffect(final BlazingTorchEffect effect) {
super(effect);
}
@Override
public BlazingTorchDamageEffect copy() {
return new BlazingTorchDamageEffect(this);
public BlazingTorchEffect copy() {
return new BlazingTorchEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(targetPointer.getFirst(game, source));
if (permanent != null && sourceId != null) {
permanent.damage(2, sourceId, game, false, true);
return true;
Object object = getValue("attachedPermanent");
Player player = game.getPlayer(source.getControllerId());
if (!(object instanceof Permanent) || player == null) {
return false;
}
Player player = game.getPlayer(targetPointer.getFirst(game, source));
if (player != null && sourceId != null) {
player.damage(2, sourceId, game);
return true;
Permanent permanent = (Permanent) object;
Permanent targetedPermanent = game.getPermanent(source.getFirstTarget());
if (targetedPermanent == null) {
Player targetedPlayer = game.getPlayer(source.getFirstTarget());
if (targetedPlayer != null) {
targetedPlayer.damage(2, permanent.getId(), game);
}
} else {
targetedPermanent.damage(2, permanent.getId(), game);
}
return false;
return true;
}
public void setSourceId(UUID sourceId) {
this.sourceId = sourceId;
@Override
public String getText(Mode mode) {
String name = "Blazing Torch";
Object object = getValue("attachedPermanent");
if (object instanceof Permanent) {
name = ((Permanent) object).getName();
}
return name + "deals 2 damage to target any target.";
}
}

View file

@ -1,35 +1,38 @@
package mage.cards.b;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.costs.common.UnattachCost;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.PreventCombatDamageToSourceEffect;
import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect;
import mage.abilities.effects.common.continuous.GainAbilityWithAttachmentEffect;
import mage.abilities.keyword.EquipAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.SubType;
import java.util.UUID;
/**
*
* @author LevelX2
*/
public final class BlindingPowder extends CardImpl {
public BlindingPowder(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{1}");
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{1}");
this.subtype.add(SubType.EQUIPMENT);
// Equipped creature has "Unattach Blinding Powder: Prevent all combat damage that would be dealt to this creature this turn."
Effect effect = new PreventCombatDamageToSourceEffect(Duration.EndOfTurn);
effect.setText("Prevent all combat damage that would be dealt to this creature this turn");
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new UnattachCost(this.getName(), this.getId()));
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(ability, AttachmentType.EQUIPMENT, Duration.WhileOnBattlefield)));
this.addAbility(new SimpleStaticAbility(new GainAbilityWithAttachmentEffect(
"equipped creature has \"Unattach {this}: Prevent all combat damage " +
"that would be dealt to this creature this turn.\"",
new PreventCombatDamageToSourceEffect(Duration.EndOfTurn)
.setText("Prevent all combat damage that would be dealt to this creature this turn"),
null, new UnattachCost()
)));
// Equip {2}
this.addAbility(new EquipAbility(Outcome.PreventDamage, new GenericManaCost(2)));
}

View file

@ -1,42 +1,39 @@
package mage.cards.h;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.common.UnattachCost;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.DestroyTargetEffect;
import mage.abilities.effects.common.continuous.BoostEnchantedEffect;
import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect;
import mage.abilities.effects.common.continuous.BoostEquippedEffect;
import mage.abilities.effects.common.continuous.GainAbilityWithAttachmentEffect;
import mage.abilities.keyword.EquipAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.target.common.TargetCreaturePermanent;
import java.util.UUID;
/**
*
* @author Galatolol
*/
public final class Heartseeker extends CardImpl {
public Heartseeker(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{4}");
this.subtype.add(SubType.EQUIPMENT);
// Equipped creature gets +2/+1 and has "{tap}, Unattach Heartseeker: Destroy target creature."
Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(2, 1, Duration.WhileOnBattlefield));
Ability gainedAbility = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DestroyTargetEffect(), new TapSourceCost());
gainedAbility.addCost(new UnattachCost(this.getName(), this.getId()));
gainedAbility.addTarget(new TargetCreaturePermanent());
Effect effect = new GainAbilityAttachedEffect(gainedAbility, AttachmentType.EQUIPMENT);
effect.setText("and has \"{T}, Unattach {this}: Destroy target creature.\"");
ability.addEffect(effect);
Ability ability = new SimpleStaticAbility(new BoostEquippedEffect(2, 1));
ability.addEffect(new GainAbilityWithAttachmentEffect(
"and has \"{T}, Unattach {this}: Destroy target creature.\"", new DestroyTargetEffect(),
new TargetCreaturePermanent(), new UnattachCost(), new TapSourceCost()
));
this.addAbility(ability);
// Equip {5}

View file

@ -1,37 +1,36 @@
package mage.cards.l;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.common.UnattachCost;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.common.TapTargetEffect;
import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect;
import mage.abilities.effects.common.continuous.GainAbilityWithAttachmentEffect;
import mage.abilities.keyword.EquipAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.target.common.TargetCreaturePermanent;
import java.util.UUID;
/**
*
* @author Plopman
*/
public final class LeoninBola extends CardImpl {
public LeoninBola(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{1}");
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{1}");
this.subtype.add(SubType.EQUIPMENT);
// Equipped creature has "{tap}, Unattach Leonin Bola: Tap target creature."
Ability gainAbility = new SimpleActivatedAbility(Zone.BATTLEFIELD, new TapTargetEffect(), new TapSourceCost());
gainAbility.addCost(new UnattachCost(this.getName(), this.getId()));
gainAbility.addTarget(new TargetCreaturePermanent());
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(gainAbility, AttachmentType.EQUIPMENT)));
this.addAbility(new SimpleStaticAbility(new GainAbilityWithAttachmentEffect(
"equipped creature has \"{tap}, Unattach {this}: Tap target creature.\"",
new TapTargetEffect(), new TargetCreaturePermanent(), new UnattachCost(), new TapSourceCost()
)));
// Equip {1}
this.addAbility(new EquipAbility(Outcome.AddAbility, new GenericManaCost(1)));
}

View file

@ -1,37 +1,29 @@
package mage.cards.m;
import java.util.UUID;
import mage.abilities.common.EntersBattlefieldAbility;
import mage.abilities.effects.common.CopyPermanentEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.filter.FilterPermanent;
import mage.filter.StaticFilters;
import java.util.UUID;
/**
*
* @author LevelX2
*/
public final class MasterworkOfIngenuity extends CardImpl {
private static final FilterPermanent filter = new FilterPermanent("equipment");
static {
filter.add(CardType.ARTIFACT.getPredicate());
filter.add(SubType.EQUIPMENT.getPredicate());
}
public MasterworkOfIngenuity(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{1}");
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{1}");
this.subtype.add(SubType.EQUIPMENT);
// You may have Masterwork of Ingenuity enter the battlefield as a copy of any Equipment on the battlefield.
this.addAbility(new EntersBattlefieldAbility(new CopyPermanentEffect(filter), true));
this.addAbility(new EntersBattlefieldAbility(new CopyPermanentEffect(StaticFilters.FILTER_PERMANENT_EQUIPMENT), true));
}
public MasterworkOfIngenuity(final MasterworkOfIngenuity card) {
private MasterworkOfIngenuity(final MasterworkOfIngenuity card) {
super(card);
}

View file

@ -1,17 +1,21 @@
package mage.cards.r;
import mage.abilities.Ability;
import mage.abilities.Mode;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.common.UnattachCost;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect;
import mage.abilities.effects.common.continuous.GainAbilityWithAttachmentEffect;
import mage.abilities.keyword.EquipAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
@ -29,10 +33,12 @@ public final class RazorBoomerang extends CardImpl {
this.subtype.add(SubType.EQUIPMENT);
// Equipped creature has "{tap}, Unattach Razor Boomerang: Razor Boomerang deals 1 damage to any target. Return Razor Boomerang to its owner's hand."
Ability gainAbility = new SimpleActivatedAbility(Zone.BATTLEFIELD, new RazorBoomerangEffect(this.getId()), new TapSourceCost());
gainAbility.addCost(new UnattachCost(this.getName(), this.getId()));
gainAbility.addTarget(new TargetAnyTarget());
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(gainAbility, AttachmentType.EQUIPMENT)));
this.addAbility(new SimpleStaticAbility(new GainAbilityWithAttachmentEffect(
"equipped creature has \"{tap}, Unattach {this}: " +
"{this} deals 1 damage to any target. Return {this} to its owner's hand.\"",
new RazorBoomerangEffect(), new TargetAnyTarget(),
new UnattachCost(), new TapSourceCost()
)));
// Equip {2}
this.addAbility(new EquipAbility(Outcome.AddAbility, new GenericManaCost(2)));
@ -50,41 +56,46 @@ public final class RazorBoomerang extends CardImpl {
class RazorBoomerangEffect extends OneShotEffect {
private static String text = "Razor Boomerang deals 1 damage to any target. Return Razor Boomerang to its owner's hand";
private UUID attachmentid;
RazorBoomerangEffect(UUID attachmentid) {
super(Outcome.Damage);
this.attachmentid = attachmentid;
staticText = text;
RazorBoomerangEffect() {
super(Outcome.Benefit);
}
RazorBoomerangEffect(RazorBoomerangEffect effect) {
private RazorBoomerangEffect(final RazorBoomerangEffect effect) {
super(effect);
this.attachmentid = effect.attachmentid;
}
@Override
public boolean apply(Game game, Ability source) {
for (UUID target : targetPointer.getTargets(game, source)) {
Permanent creature = game.getPermanent(target);
if (creature != null) {
creature.damage(1, attachmentid, game, false, true);
}
Player player = game.getPlayer(target);
if (player != null) {
player.damage(1, attachmentid, game);
}
}
Permanent razor = game.getPermanent(attachmentid);
if (razor != null) {
razor.moveToZone(Zone.HAND, source.getSourceId(), game, true);
}
return true;
}
@Override
public RazorBoomerangEffect copy() {
return new RazorBoomerangEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Object object = getValue("attachedPermanent");
Player player = game.getPlayer(source.getControllerId());
if (!(object instanceof Permanent) || player == null) {
return false;
}
Permanent permanent = (Permanent) object;
Permanent targetedPermanent = game.getPermanent(source.getFirstTarget());
if (targetedPermanent == null) {
Player targetedPlayer = game.getPlayer(source.getFirstTarget());
if (targetedPlayer != null) {
targetedPlayer.damage(1, permanent.getId(), game);
}
} else {
targetedPermanent.damage(1, permanent.getId(), game);
}
return player.moveCards(permanent, Zone.HAND, source, game);
}
@Override
public String getText(Mode mode) {
String name = "Razor Boomerang";
Object object = getValue("attachedPermanent");
if (object instanceof Permanent) {
name = ((Permanent) object).getName();
}
return name + " deals 1 damage to any target. Return " + name + " to its owner's hand.";
}
}

View file

@ -1,44 +1,44 @@
package mage.cards.s;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.Mode;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.costs.Cost;
import mage.abilities.costs.CostImpl;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.common.UnattachCost;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect;
import mage.abilities.effects.common.continuous.GainAbilityWithAttachmentEffect;
import mage.abilities.effects.common.continuous.GainControlTargetEffect;
import mage.abilities.keyword.EquipAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetCreaturePermanent;
import mage.target.targetpointer.FixedTarget;
import java.util.UUID;
/**
*
* @author LevelX2
* @author TheElk801
*/
public final class Shuriken extends CardImpl {
public Shuriken(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{1}");
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{1}");
this.subtype.add(SubType.EQUIPMENT);
// Equipped creature has "{tap}, Unattach Shuriken: Shuriken deals 2 damage to target creature. That creature's controller gains control of Shuriken unless it was unattached from a Ninja."
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ShurikenDamageEffect(), new TapSourceCost());
ability.addTarget(new TargetCreaturePermanent());
ability.addCost(new ShurikenUnattachCost());
ability.addEffect(new ShurikenControlEffect());
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(ability, AttachmentType.EQUIPMENT, Duration.WhileOnBattlefield)));
this.addAbility(new SimpleStaticAbility(new GainAbilityWithAttachmentEffect(
"equipped creature has \"{tap}, Unattach {this}: {this} deals 2 damage to target creature. " +
"That creature's controller gains control of {this} unless it was unattached from a Ninja.\"",
new ShurikenEffect(), new TargetCreaturePermanent(), new UnattachCost(), new TapSourceCost()
)));
// Equip {2}
this.addAbility(new EquipAbility(Outcome.PreventDamage, new GenericManaCost(2)));
@ -54,181 +54,49 @@ public final class Shuriken extends CardImpl {
}
}
class ShurikenDamageEffect extends OneShotEffect {
class ShurikenEffect extends OneShotEffect {
public ShurikenDamageEffect() {
super(Outcome.Damage);
this.staticText = "Shuriken deals 2 damage to target creature";
ShurikenEffect() {
super(Outcome.Benefit);
}
public ShurikenDamageEffect(final ShurikenDamageEffect effect) {
private ShurikenEffect(final ShurikenEffect effect) {
super(effect);
}
@Override
public ShurikenDamageEffect copy() {
return new ShurikenDamageEffect(this);
public ShurikenEffect copy() {
return new ShurikenEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent equipment = null;
for(Cost cost : source.getCosts()) {
if (cost instanceof ShurikenUnattachCost) {
equipment = ((ShurikenUnattachCost) cost).getEquipment();
break;
}
Object object = getValue("attachedPermanent");
Player player = game.getPlayer(source.getControllerId());
Permanent targetedPermanent = game.getPermanent(source.getFirstTarget());
if (!(object instanceof Permanent) || player == null || targetedPermanent == null) {
return false;
}
if (equipment != null) {
Permanent creature = game.getPermanent(this.getTargetPointer().getFirst(game, source));
if (creature != null) {
creature.damage(2, equipment.getId(), game, false, true);
}
Permanent equipment = (Permanent) object;
targetedPermanent.damage(2, equipment.getId(), game);
Permanent attached = source.getSourcePermanentOrLKI(game);
if (attached != null && attached.hasSubtype(SubType.NINJA, game)) {
return true;
}
return false;
}
}
class ShurikenUnattachCost extends CostImpl {
Permanent equipment;
public ShurikenUnattachCost() {
this.text = "Unattach Shuriken";
}
public ShurikenUnattachCost(final ShurikenUnattachCost cost) {
super(cost);
this.equipment = cost.equipment;
}
@Override
public boolean pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana, Cost costToPay) {
Permanent permanent = game.getPermanent(sourceId);
if (permanent != null) {
for (UUID attachmentId :permanent.getAttachments()) {
Permanent attachment = game.getPermanent(attachmentId);
if (attachment != null && attachment.getName().equals("Shuriken")) {
paid = permanent.removeAttachment(attachmentId, game);
if (paid) {
equipment = attachment;
break;
}
}
}
}
return paid;
}
@Override
public boolean canPay(Ability ability, UUID sourceId, UUID controllerId, Game game) {
Permanent permanent = game.getPermanent(sourceId);
if (permanent != null) {
for (UUID attachmentId :permanent.getAttachments()) {
Permanent attachment = game.getPermanent(attachmentId);
if (attachment != null && attachment.getName().equals("Shuriken")) {
return true;
}
}
}
return false;
}
@Override
public ShurikenUnattachCost copy() {
return new ShurikenUnattachCost(this);
}
public Permanent getEquipment() {
return equipment;
}
}
class ShurikenControlEffect extends OneShotEffect {
public ShurikenControlEffect() {
super(Outcome.Benefit);
this.staticText = "That creature's controller gains control of Shuriken unless it was unattached from a Ninja";
}
public ShurikenControlEffect(final ShurikenControlEffect effect) {
super(effect);
}
@Override
public ShurikenControlEffect copy() {
return new ShurikenControlEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent equipment = null; // TODO: Meanwhile blinked object would be found regardless
for(Cost cost : source.getCosts()) {
if (cost instanceof ShurikenUnattachCost) {
equipment = ((ShurikenUnattachCost) cost).getEquipment();
}
}
if (equipment != null) {
Permanent creature = game.getPermanent(source.getSourceId());
if (creature != null) {
if (!creature.hasSubtype(SubType.NINJA, game)) {
Permanent damagedCreature = game.getPermanent(this.getTargetPointer().getFirst(game, source));
if (damagedCreature == null) {
damagedCreature = (Permanent) game.getLastKnownInformation(this.getTargetPointer().getFirst(game, source), Zone.BATTLEFIELD);
}
if (damagedCreature != null) {
ContinuousEffect effect = new ShurikenGainControlEffect(Duration.EndOfGame, damagedCreature.getControllerId());
effect.setTargetPointer(new FixedTarget(equipment.getId()));
game.addEffect(effect, source);
return true;
} else {
return false;
}
}
return true;
}
}
return false;
}
}
class ShurikenGainControlEffect extends ContinuousEffectImpl {
UUID controller;
public ShurikenGainControlEffect(Duration duration, UUID controller) {
super(duration, Layer.ControlChangingEffects_2, SubLayer.NA, Outcome.GainControl);
this.controller = controller;
}
public ShurikenGainControlEffect(final ShurikenGainControlEffect effect) {
super(effect);
this.controller = effect.controller;
}
@Override
public ShurikenGainControlEffect copy() {
return new ShurikenGainControlEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(source.getFirstTarget());
if (targetPointer != null) {
permanent = game.getPermanent(targetPointer.getFirst(game, source));
}
if (permanent != null) {
return permanent.changeControllerId(controller, game);
}
return false;
game.addEffect(new GainControlTargetEffect(
Duration.Custom, true, attached.getControllerId()
).setTargetPointer(new FixedTarget(equipment, game)), source);
return true;
}
@Override
public String getText(Mode mode) {
return "Gain control of Shuriken";
String name = "Shuriken";
Object object = getValue("attachedPermanent");
if (object instanceof Permanent) {
name = ((Permanent) object).getName();
}
return name + "deals 2 damage to target creature. That creature's controller gains control of "
+ name + " unless it was unattached from a Ninja.";
}
}

View file

@ -1,50 +1,49 @@
package mage.cards.s;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.common.UnattachCost;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.dynamicvalue.common.SourcePermanentPowerCount;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect;
import mage.abilities.effects.common.continuous.GainAbilityWithAttachmentEffect;
import mage.abilities.keyword.EquipAbility;
import mage.abilities.keyword.FirstStrikeAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.AttachmentType;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.target.common.TargetPlayerOrPlaneswalker;
import mage.constants.SubType;
import mage.target.TargetPlayer;
import java.util.UUID;
/**
*
* @author AlumiuN
*/
public final class SurestrikeTrident extends CardImpl {
private static final DynamicValue xValue = new SourcePermanentPowerCount();
public SurestrikeTrident(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}");
this.subtype.add(SubType.EQUIPMENT);
// Equipped creature has first strike and "{T}, Unattach Surestrike Trident: This creature deals damage equal to its power to target player."
Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(FirstStrikeAbility.getInstance(), AttachmentType.EQUIPMENT));
DynamicValue xValue = new SourcePermanentPowerCount();
Effect effect = new DamageTargetEffect(xValue);
effect.setText("This creature deals damage equal to its power to target player or planeswalker");
Ability gainedAbility = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new TapSourceCost());
gainedAbility.addTarget(new TargetPlayerOrPlaneswalker());
gainedAbility.addCost(new UnattachCost(this.getName(), this.getId()));
effect = new GainAbilityAttachedEffect(gainedAbility, AttachmentType.EQUIPMENT);
effect.setText("and \"{T}, Unattach {this}: This creature deals damage equal to its power to target player.\"");
ability.addEffect(effect);
Ability ability = new SimpleStaticAbility(new GainAbilityAttachedEffect(
FirstStrikeAbility.getInstance(), AttachmentType.EQUIPMENT
));
ability.addEffect(new GainAbilityWithAttachmentEffect(
"and \"{T}, Unattach {this}: This creature deals damage equal to its power to target player.\"",
new DamageTargetEffect(xValue)
.setText("This creature deals damage equal to its power to target player or planeswalker"),
new TargetPlayer(), new UnattachCost(), new TapSourceCost()
));
this.addAbility(ability);
// Equip {4}

View file

@ -0,0 +1,84 @@
package org.mage.test.cards.single.zen;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
* @author TheElk801
*/
public class BlazingTorchTest extends CardTestPlayerBase {
private static final String plains = "Plains";
private static final String torch = "Blazing Torch";
private static final String lion = "Silvercoat Lion";
private static final String masterwork = "Masterwork of Ingenuity";
private static final String halo = "Runed Halo";
@Test
public void testCard() {
addCard(Zone.BATTLEFIELD, playerA, plains);
addCard(Zone.BATTLEFIELD, playerA, lion);
addCard(Zone.BATTLEFIELD, playerA, torch);
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Equip");
activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{T},", playerB);
setStopAt(1, PhaseStep.END_TURN);
execute();
assertLife(playerA, 20);
assertLife(playerB, 18);
assertPermanentCount(playerA, lion, 1);
assertPermanentCount(playerA, torch, 0);
assertGraveyardCount(playerA, torch, 1);
}
@Test
public void testCardCopied() {
addCard(Zone.BATTLEFIELD, playerA, plains, 2);
addCard(Zone.BATTLEFIELD, playerA, lion);
addCard(Zone.HAND, playerA, masterwork);
addCard(Zone.BATTLEFIELD, playerB, torch);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, masterwork);
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Equip");
activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{T},", playerB);
setStopAt(1, PhaseStep.END_TURN);
execute();
assertLife(playerA, 20);
assertLife(playerB, 18);
assertPermanentCount(playerA, lion, 1);
assertPermanentCount(playerA, torch, 0);
assertPermanentCount(playerB, torch, 1);
assertGraveyardCount(playerA, masterwork, 1);
assertGraveyardCount(playerB, torch, 0);
}
@Test
public void testRunedHalo() {
addCard(Zone.BATTLEFIELD, playerA, plains);
addCard(Zone.BATTLEFIELD, playerA, lion);
addCard(Zone.BATTLEFIELD, playerA, torch);
addCard(Zone.BATTLEFIELD, playerB, plains, 2);
addCard(Zone.HAND, playerB, halo);
setChoice(playerB, torch);
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, halo);
activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "Equip");
activateAbility(3, PhaseStep.POSTCOMBAT_MAIN, playerA, "{T},", playerB);
setStopAt(3, PhaseStep.END_TURN);
execute();
assertLife(playerA, 20);
assertLife(playerB, 20); // Ability resolves as it's from the equipped creature but damage is from torch and is prevented
assertPermanentCount(playerA, lion, 1);
assertPermanentCount(playerA, torch, 0);
assertGraveyardCount(playerA, torch, 1);
}
}

View file

@ -0,0 +1,53 @@
package mage.abilities.costs;
import mage.MageObject;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.game.Game;
import mage.game.permanent.Permanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public abstract class UseAttachedCost extends CostImpl {
protected MageObjectReference mageObjectReference;
protected String name = "{this}";
protected UseAttachedCost() {
super();
}
protected UseAttachedCost(final UseAttachedCost cost) {
super(cost);
this.mageObjectReference = cost.mageObjectReference;
this.name = cost.name;
}
@Override
public boolean canPay(Ability ability, UUID sourceId, UUID controllerId, Game game) {
if (mageObjectReference == null) {
return false;
}
Permanent permanent = game.getPermanent(sourceId);
return permanent != null
&& permanent
.getAttachments()
.stream()
.anyMatch(uuid -> mageObjectReference.refersTo(uuid, game));
}
public UseAttachedCost setMageObjectReference(Ability source, Game game) {
this.mageObjectReference = new MageObjectReference(source.getSourceId(), game);
MageObject object = game.getObject(source.getSourceId());
if (object != null) {
this.name = object.getName();
}
return this;
}
@Override
public abstract UseAttachedCost copy();
}

View file

@ -0,0 +1,56 @@
package mage.abilities.costs.common;
import mage.abilities.Ability;
import mage.abilities.costs.Cost;
import mage.abilities.costs.UseAttachedCost;
import mage.game.Game;
import mage.game.permanent.Permanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public class SacrificeAttachmentCost extends UseAttachedCost {
public SacrificeAttachmentCost() {
super();
}
public SacrificeAttachmentCost(final SacrificeAttachmentCost cost) {
super(cost);
}
@Override
public boolean pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana, Cost costToPay) {
if (mageObjectReference == null) {
return false;
}
Permanent permanent = game.getPermanent(sourceId);
if (permanent == null) {
return paid;
}
for (UUID attachmentId : permanent.getAttachments()) {
if (!this.mageObjectReference.refersTo(attachmentId, game)) {
continue;
}
Permanent attachment = game.getPermanent(attachmentId);
paid = attachment != null && attachment.sacrifice(sourceId, game);
if (paid) {
break;
}
}
return paid;
}
@Override
public SacrificeAttachmentCost copy() {
return new SacrificeAttachmentCost(this);
}
@Override
public String getText() {
return "sacrifice " + this.name;
}
}

View file

@ -1,64 +1,55 @@
package mage.abilities.costs.common;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.costs.Cost;
import mage.abilities.costs.CostImpl;
import mage.abilities.costs.UseAttachedCost;
import mage.game.Game;
import mage.game.permanent.Permanent;
import java.util.UUID;
/**
* @author Galatolol
* @author TheElk801
*/
public class UnattachCost extends CostImpl {
public class UnattachCost extends UseAttachedCost {
protected UUID sourceEquipmentId;
public UnattachCost(String name, UUID sourceId) {
this.text = "Unattach " + name;
this.sourceEquipmentId = sourceId;
public UnattachCost() {
super();
}
public UnattachCost(final UnattachCost cost) {
super(cost);
this.sourceEquipmentId = cost.sourceEquipmentId;
}
@Override
public boolean pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana, Cost costToPay) {
Permanent permanent = game.getPermanent(sourceId);
if (permanent != null) {
for (UUID attachmentId : permanent.getAttachments()) {
Permanent attachment = game.getPermanent(attachmentId);
if (attachment != null && attachment.getId().equals(sourceEquipmentId)) {
paid = permanent.removeAttachment(attachmentId, game);
if (paid) {
break;
}
}
}
if (mageObjectReference == null) {
return false;
}
Permanent permanent = game.getPermanent(sourceId);
if (permanent == null) {
return paid;
}
for (UUID attachmentId : permanent.getAttachments()) {
if (!this.mageObjectReference.refersTo(attachmentId, game)) {
continue;
}
paid = permanent.removeAttachment(attachmentId, game);
if (paid) {
break;
}
}
return paid;
}
@Override
public boolean canPay(Ability ability, UUID sourceId, UUID controllerId, Game game) {
Permanent permanent = game.getPermanent(sourceId);
if (permanent != null) {
for (UUID attachmentId : permanent.getAttachments()) {
Permanent attachment = game.getPermanent(attachmentId);
if (attachment != null && attachment.getId().equals(sourceEquipmentId)) {
return true;
}
}
}
return false;
}
@Override
public UnattachCost copy() {
return new UnattachCost(this);
}
@Override
public String getText() {
return "unattach " + this.name;
}
}

View file

@ -0,0 +1,119 @@
package mage.abilities.effects.common.continuous;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.Cost;
import mage.abilities.costs.Costs;
import mage.abilities.costs.CostsImpl;
import mage.abilities.costs.UseAttachedCost;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.abilities.effects.Effect;
import mage.abilities.effects.Effects;
import mage.constants.Duration;
import mage.constants.Layer;
import mage.constants.Outcome;
import mage.constants.SubLayer;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.target.Target;
import mage.target.Targets;
import mage.target.targetpointer.FixedTarget;
import java.util.Arrays;
/**
* @author TheElk801
*/
public class GainAbilityWithAttachmentEffect extends ContinuousEffectImpl {
private final Effects effects = new Effects();
private final Targets targets = new Targets();
private final Costs costs = new CostsImpl();
private final UseAttachedCost useAttachedCost;
public GainAbilityWithAttachmentEffect(String rule, Effect effect, Target target, UseAttachedCost attachedCost, Cost... costs) {
this(rule, new Effects(effect), new Targets(target), attachedCost, costs);
}
public GainAbilityWithAttachmentEffect(String rule, Effects effects, Targets targets, UseAttachedCost attachedCost, Cost... costs) {
super(Duration.WhileOnBattlefield, Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, Outcome.AddAbility);
this.staticText = rule;
this.effects.addAll(effects);
this.targets.addAll(targets);
this.costs.addAll(Arrays.asList(costs));
this.useAttachedCost = attachedCost;
this.generateGainAbilityDependencies(makeAbility(this.effects, this.targets, this.costs), null);
}
public GainAbilityWithAttachmentEffect(final GainAbilityWithAttachmentEffect effect) {
super(effect);
this.effects.addAll(effect.effects);
this.targets.addAll(effect.targets);
this.costs.addAll(effect.costs);
this.useAttachedCost = effect.useAttachedCost.copy();
}
@Override
public GainAbilityWithAttachmentEffect copy() {
return new GainAbilityWithAttachmentEffect(this);
}
@Override
public void init(Ability source, Game game) {
super.init(source, game);
if (affectedObjectsSet) {
Permanent equipment = game.getPermanentOrLKIBattlefield(source.getSourceId());
if (equipment != null && equipment.getAttachedTo() != null) {
this.setTargetPointer(new FixedTarget(equipment.getAttachedTo(), game.getState().getZoneChangeCounter(equipment.getAttachedTo())));
}
}
}
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = null;
if (affectedObjectsSet) {
permanent = game.getPermanent(targetPointer.getFirst(game, source));
if (permanent == null) {
discard();
return true;
}
} else {
Permanent equipment = game.getPermanent(source.getSourceId());
if (equipment != null && equipment.getAttachedTo() != null) {
permanent = game.getPermanentOrLKIBattlefield(equipment.getAttachedTo());
}
}
if (permanent == null) {
return true;
}
Ability ability = makeAbility(this.effects, this.targets, this.costs);
ability.getEffects().setValue("attachedPermanent", game.getPermanent(source.getSourceId()));
ability.addCost(useAttachedCost.copy().setMageObjectReference(source, game));
permanent.addAbility(ability, source.getSourceId(), game);
return true;
}
private static Ability makeAbility(Effects effects, Targets targets, Cost... costs) {
Ability ability = new SimpleActivatedAbility(null, null);
for (Effect effect : effects) {
if (effect == null) {
continue;
}
ability.addEffect(effect.copy());
}
for (Target target : targets) {
if (target == null) {
continue;
}
ability.addTarget(target);
}
for (Cost cost : costs) {
if (cost == null) {
continue;
}
ability.addCost(cost.copy());
}
return ability;
}
}