mirror of
https://github.com/magefree/mage.git
synced 2026-01-26 21:29:17 -08:00
[LGN] Rework Whipgrass Entangler (#10802)
* Rework Whipgrass Entangler Made a class for "Ability linked with an Effect", that also takes responsability of manually calling its effect's newId method. * apply review & cleanup
This commit is contained in:
parent
01e181013b
commit
92f0f84b23
5 changed files with 280 additions and 21 deletions
|
|
@ -0,0 +1,82 @@
|
|||
package mage.abilities.common;
|
||||
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.constants.Zone;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Warning: please test with a lot of care when using this class for new things.
|
||||
* <p>
|
||||
* A static Ability linked to an Effect.
|
||||
* The parent Ability does take responsability of setting the id for the child.
|
||||
*
|
||||
* @author Susucr
|
||||
*/
|
||||
public class LinkedEffectIdStaticAbility extends SimpleStaticAbility {
|
||||
|
||||
public interface ChildEffect extends Effect {
|
||||
/**
|
||||
* Set the link for the child.
|
||||
*/
|
||||
void setParentLinkHandshake(UUID parentLinkHandshake);
|
||||
|
||||
/**
|
||||
* The child Id should only change on copy when the parent wants it to.
|
||||
*/
|
||||
void manualNewId();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The handshake UUID between this parent ability and its child.
|
||||
*/
|
||||
private UUID linkedHandshake;
|
||||
|
||||
public LinkedEffectIdStaticAbility(ChildEffect effect) {
|
||||
this(Zone.BATTLEFIELD, effect);
|
||||
}
|
||||
|
||||
public LinkedEffectIdStaticAbility(Zone zone, ChildEffect effect) {
|
||||
super(Zone.BATTLEFIELD, effect);
|
||||
this.linkedHandshake = UUID.randomUUID();
|
||||
initHandshake();
|
||||
setEffectIdManually();
|
||||
}
|
||||
|
||||
private LinkedEffectIdStaticAbility(final LinkedEffectIdStaticAbility effect) {
|
||||
super(effect);
|
||||
this.linkedHandshake = UUID.randomUUID();
|
||||
initHandshake();
|
||||
}
|
||||
|
||||
@Override
|
||||
public LinkedEffectIdStaticAbility copy() {
|
||||
return new LinkedEffectIdStaticAbility(this);
|
||||
}
|
||||
|
||||
private void initHandshake() {
|
||||
this.linkedHandshake = UUID.randomUUID();
|
||||
CardUtil.castStream(this.getEffects().stream(), ChildEffect.class)
|
||||
.filter(Objects::nonNull)
|
||||
.forEach(e -> e.setParentLinkHandshake(linkedHandshake));
|
||||
}
|
||||
|
||||
public void setEffectIdManually() {
|
||||
CardUtil.castStream(this.getEffects().stream(), ChildEffect.class)
|
||||
.filter(Objects::nonNull)
|
||||
.forEach(e -> e.manualNewId());
|
||||
}
|
||||
|
||||
public boolean checkLinked(UUID handshake) {
|
||||
return linkedHandshake.equals(handshake);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void newId() {
|
||||
super.newId();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -8,7 +8,6 @@ import mage.constants.Duration;
|
|||
import mage.constants.Outcome;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.events.GameEvent.EventType;
|
||||
|
||||
/**
|
||||
* @author LevelX2
|
||||
|
|
@ -26,7 +25,7 @@ public class CantAttackBlockUnlessPaysSourceEffect extends PayCostToAttackBlockE
|
|||
staticText = "{this} can't " + restrictType.toString() + " unless you pay " + (manaCosts == null ? "" : manaCosts.getText());
|
||||
}
|
||||
|
||||
public CantAttackBlockUnlessPaysSourceEffect(CantAttackBlockUnlessPaysSourceEffect effect) {
|
||||
protected CantAttackBlockUnlessPaysSourceEffect(final CantAttackBlockUnlessPaysSourceEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,13 +3,12 @@ package mage.abilities.effects.common.continuous;
|
|||
import mage.MageObjectReference;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.Mode;
|
||||
import mage.abilities.common.LinkedEffectIdStaticAbility;
|
||||
import mage.abilities.effects.ContinuousEffectImpl;
|
||||
import mage.cards.Card;
|
||||
import mage.constants.*;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.target.Target;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
|
|
@ -18,7 +17,7 @@ import java.util.*;
|
|||
*/
|
||||
public class GainAbilityTargetEffect extends ContinuousEffectImpl {
|
||||
|
||||
protected Ability ability;
|
||||
protected final Ability ability;
|
||||
|
||||
// shall a card gain the ability (otherwise a permanent)
|
||||
private final boolean useOnCard; // only one card per ability supported
|
||||
|
|
@ -43,7 +42,8 @@ public class GainAbilityTargetEffect extends ContinuousEffectImpl {
|
|||
|
||||
public GainAbilityTargetEffect(Ability ability, Duration duration, String rule, boolean useOnCard) {
|
||||
super(duration, Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, ability.getEffects().getOutcome(ability, Outcome.AddAbility));
|
||||
this.ability = ability;
|
||||
this.ability = copyAbility(ability); // See the method's comment, ability.copy() is not enough.
|
||||
|
||||
this.staticText = rule;
|
||||
this.useOnCard = useOnCard;
|
||||
|
||||
|
|
@ -52,8 +52,7 @@ public class GainAbilityTargetEffect extends ContinuousEffectImpl {
|
|||
|
||||
protected GainAbilityTargetEffect(final GainAbilityTargetEffect effect) {
|
||||
super(effect);
|
||||
this.ability = effect.ability.copy();
|
||||
this.ability.newId(); // This is needed if the effect is copied e.g. by a clone so the ability can be added multiple times to permanents
|
||||
this.ability = copyAbility(effect.ability); // See the method's comment, ability.copy() is not enough.
|
||||
this.useOnCard = effect.useOnCard;
|
||||
this.waitingCardPermanent = effect.waitingCardPermanent;
|
||||
this.durationPhaseStep = effect.durationPhaseStep;
|
||||
|
|
@ -202,6 +201,23 @@ public class GainAbilityTargetEffect extends ContinuousEffectImpl {
|
|||
return affectedTargets > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copying the ability and providing ability is needed in a few situations,
|
||||
* The copy in order to have internal fields be proper to that ability in particular.
|
||||
* Id must be different for the copy, for a few things like the GainAbilityTargetEffect gained
|
||||
* by a clone, or in the case of an activated ability, called multiple times on the same target,
|
||||
* and thus the ability should be gained multiple times.
|
||||
*/
|
||||
|
||||
private Ability copyAbility(Ability toCopyAbility) {
|
||||
Ability ability = toCopyAbility.copy();
|
||||
ability.newId();
|
||||
if (ability instanceof LinkedEffectIdStaticAbility) {
|
||||
((LinkedEffectIdStaticAbility) ability).setEffectIdManually();
|
||||
}
|
||||
return ability;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText(Mode mode) {
|
||||
if (staticText != null && !staticText.isEmpty()) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue