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

@ -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;
}
}