mirror of
https://github.com/magefree/mage.git
synced 2026-01-26 21:29:17 -08:00
support until your next turn delayed triggers (#12233)
This commit is contained in:
parent
614be8e928
commit
3abce2f5c8
17 changed files with 502 additions and 347 deletions
|
|
@ -49,10 +49,14 @@ public class DelayedTriggeredAbilities extends AbilitiesImpl<DelayedTriggeredAbi
|
|||
this.removeIf(ability -> ability.getDuration() == Duration.EndOfTurn); // TODO: add Duration.EndOfYourTurn like effects
|
||||
}
|
||||
|
||||
public void removeStartOfNewTurn(Game game) {
|
||||
this.removeIf(ability -> ability.getDuration() == Duration.UntilYourNextTurn
|
||||
&& game.getActivePlayerId().equals(ability.getControllerId())
|
||||
);
|
||||
}
|
||||
|
||||
public void removeEndOfCombatAbilities() {
|
||||
this.removeIf(ability -> ability.getDuration() == Duration.EndOfCombat);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -63,31 +63,32 @@ public class DealsDamageToACreatureAllTriggeredAbility extends TriggeredAbilityI
|
|||
|
||||
@Override
|
||||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
Permanent permanent = game.getPermanent(event.getTargetId());
|
||||
if (permanent == null || !permanent.isCreature(game)) {
|
||||
return false;
|
||||
}
|
||||
if (combatOnly && !((DamagedEvent) event).isCombatDamage()) {
|
||||
return false;
|
||||
}
|
||||
permanent = game.getPermanentOrLKIBattlefield(event.getSourceId());
|
||||
if (!filterPermanent.match(permanent, getControllerId(), this, game)) {
|
||||
Permanent permanentDealtDamage = game.getPermanent(event.getTargetId());
|
||||
if (permanentDealtDamage == null || !permanentDealtDamage.isCreature(game)) {
|
||||
return false;
|
||||
}
|
||||
this.getEffects().setValue("damage", event.getAmount());
|
||||
Permanent permanentDealingDamage = game.getPermanentOrLKIBattlefield(event.getSourceId());
|
||||
if (!filterPermanent.match(permanentDealingDamage, getControllerId(), this, game)) {
|
||||
return false;
|
||||
}
|
||||
int damageAmount = event.getAmount();
|
||||
if (damageAmount < 1) {
|
||||
return false;
|
||||
}
|
||||
this.getEffects().setValue("damage", damageAmount);
|
||||
this.getEffects().setValue("sourceId", event.getSourceId());
|
||||
switch (setTargetPointer) {
|
||||
case PLAYER:
|
||||
this.getEffects().setTargetPointer(new FixedTarget(permanent.getControllerId()));
|
||||
this.getEffects().setTargetPointer(new FixedTarget(permanentDealingDamage.getControllerId()));
|
||||
break;
|
||||
case PERMANENT:
|
||||
this.getEffects().setTargetPointer(new FixedTarget(permanent, game));
|
||||
this.getEffects().setTargetPointer(new FixedTarget(permanentDealingDamage, game));
|
||||
break;
|
||||
case PERMANENT_TARGET:
|
||||
Permanent permanent_target = game.getPermanentOrLKIBattlefield(event.getTargetId());
|
||||
if (permanent_target != null) {
|
||||
this.getEffects().setTargetPointer(new FixedTarget(permanent_target, game));
|
||||
}
|
||||
this.getEffects().setTargetPointer(new FixedTarget(permanentDealtDamage, game));
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,80 @@
|
|||
package mage.abilities.common;
|
||||
|
||||
import mage.abilities.TriggeredAbilityImpl;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.constants.SetTargetPointer;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.DamagedEvent;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.target.targetpointer.FixedTarget;
|
||||
|
||||
/**
|
||||
* @author Susucr
|
||||
*/
|
||||
public class DealsDamageToThisAllTriggeredAbility extends TriggeredAbilityImpl {
|
||||
|
||||
private final boolean combatOnly;
|
||||
private final FilterPermanent filterPermanent;
|
||||
private final SetTargetPointer setTargetPointer;
|
||||
|
||||
public DealsDamageToThisAllTriggeredAbility(
|
||||
Effect effect, boolean optional, FilterPermanent filterPermanent,
|
||||
SetTargetPointer setTargetPointer, boolean combatOnly
|
||||
) {
|
||||
super(Zone.BATTLEFIELD, effect, optional);
|
||||
this.setTargetPointer = setTargetPointer;
|
||||
this.filterPermanent = filterPermanent;
|
||||
this.combatOnly = combatOnly;
|
||||
setTriggerPhrase("Whenever " + filterPermanent.getMessage() + " deals "
|
||||
+ (combatOnly ? "combat " : "") + "damage to a {this}, ");
|
||||
}
|
||||
|
||||
protected DealsDamageToThisAllTriggeredAbility(final DealsDamageToThisAllTriggeredAbility ability) {
|
||||
super(ability);
|
||||
this.combatOnly = ability.combatOnly;
|
||||
this.filterPermanent = ability.filterPermanent;
|
||||
this.setTargetPointer = ability.setTargetPointer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DealsDamageToThisAllTriggeredAbility copy() {
|
||||
return new DealsDamageToThisAllTriggeredAbility(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkEventType(GameEvent event, Game game) {
|
||||
return event.getType() == GameEvent.EventType.DAMAGED_PERMANENT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
if (combatOnly && !((DamagedEvent) event).isCombatDamage()) {
|
||||
return false;
|
||||
}
|
||||
if (!event.getTargetId().equals(this.sourceId)) {
|
||||
return false;
|
||||
}
|
||||
Permanent permanent = game.getPermanentOrLKIBattlefield(event.getSourceId());
|
||||
if (!filterPermanent.match(permanent, getControllerId(), this, game)) {
|
||||
return false;
|
||||
}
|
||||
int damageAmount = event.getAmount();
|
||||
if (damageAmount < 1) {
|
||||
return false;
|
||||
}
|
||||
this.getEffects().setValue("damage", damageAmount);
|
||||
this.getEffects().setValue("sourceId", event.getSourceId());
|
||||
switch (setTargetPointer) {
|
||||
case PLAYER:
|
||||
this.getEffects().setTargetPointer(new FixedTarget(permanent.getControllerId()));
|
||||
break;
|
||||
case PERMANENT:
|
||||
this.getEffects().setTargetPointer(new FixedTarget(permanent, game));
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,106 @@
|
|||
|
||||
package mage.abilities.common.delayed;
|
||||
|
||||
import mage.abilities.DelayedTriggeredAbility;
|
||||
import mage.abilities.Modes;
|
||||
import mage.abilities.TriggeredAbility;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.abilities.effects.Effects;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.EffectType;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.util.CardUtil;
|
||||
import mage.watchers.Watcher;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* "Until your next turn, [trigger]"
|
||||
*
|
||||
* @author Susucr
|
||||
*/
|
||||
public class UntilYourNextTurnDelayedTriggeredAbility extends DelayedTriggeredAbility {
|
||||
|
||||
private final TriggeredAbility trigger;
|
||||
|
||||
public UntilYourNextTurnDelayedTriggeredAbility(TriggeredAbility trigger) {
|
||||
super(null, Duration.UntilYourNextTurn);
|
||||
if (trigger.isLeavesTheBattlefieldTrigger()) {
|
||||
this.setLeavesTheBattlefieldTrigger(true);
|
||||
}
|
||||
this.trigger = trigger;
|
||||
}
|
||||
|
||||
protected UntilYourNextTurnDelayedTriggeredAbility(final UntilYourNextTurnDelayedTriggeredAbility ability) {
|
||||
super(ability);
|
||||
this.trigger = ability.trigger.copy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public UntilYourNextTurnDelayedTriggeredAbility copy() {
|
||||
return new UntilYourNextTurnDelayedTriggeredAbility(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkEventType(GameEvent event, Game game) {
|
||||
return trigger.checkEventType(event, game);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
trigger.setSourceId(this.getSourceId());
|
||||
trigger.setControllerId(this.getControllerId());
|
||||
return trigger.checkTrigger(event, game);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRule() {
|
||||
return "Until your next turn, " + CardUtil.getTextWithFirstCharLowerCase(trigger.getRule());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Effects getEffects() {
|
||||
return trigger.getEffects();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addEffect(Effect effect) {
|
||||
trigger.addEffect(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Modes getModes() {
|
||||
return trigger.getModes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Watcher> getWatchers() {
|
||||
return trigger.getWatchers();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addWatcher(Watcher watcher) {
|
||||
trigger.addWatcher(watcher);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Effects getEffects(Game game, EffectType effectType) {
|
||||
return trigger.getEffects(game, effectType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOptional() {
|
||||
return trigger.isOptional();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSourceObjectZoneChangeCounter(int sourceObjectZoneChangeCounter) {
|
||||
trigger.setSourceObjectZoneChangeCounter(sourceObjectZoneChangeCounter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSourceObjectZoneChangeCounter() {
|
||||
return trigger.getSourceObjectZoneChangeCounter();
|
||||
}
|
||||
}
|
||||
|
|
@ -699,6 +699,10 @@ public class GameState implements Serializable, Copyable<GameState> {
|
|||
game.applyEffects();
|
||||
}
|
||||
|
||||
public void removeTurnStartEffect(Game game) {
|
||||
delayed.removeStartOfNewTurn(game);
|
||||
}
|
||||
|
||||
public void addEffect(ContinuousEffect effect, Ability source) {
|
||||
addEffect(effect, null, source);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -539,6 +539,7 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
public void beginTurn(Game game) {
|
||||
resetLandsPlayed();
|
||||
updateRange(game);
|
||||
game.getState().removeTurnStartEffect(game);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue