mirror of
https://github.com/correl/mage.git
synced 2024-12-25 03:00:15 +00:00
[STX] Implemented Strict Proctor
This commit is contained in:
parent
3ba320257b
commit
f9467d5142
18 changed files with 140 additions and 27 deletions
|
@ -82,7 +82,7 @@ class ForceProjectionEffect extends OneShotEffect {
|
|||
Effect sacrificeEffect = new SacrificeSourceEffect();
|
||||
sacrificeEffect.setTargetPointer(new FixedTarget(effect.getAddedPermanent().get(0), game));
|
||||
TriggeredAbility ability = new BecomesTargetTriggeredAbility(sacrificeEffect, new FilterSpell());
|
||||
game.addTriggeredAbility(ability);
|
||||
game.addTriggeredAbility(ability, null);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -78,10 +78,10 @@ class HiddenPredatorsStateTriggeredAbility extends StateTriggeredAbility {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void trigger(Game game, UUID controllerId) {
|
||||
public void trigger(Game game, UUID controllerId, GameEvent triggeringEvent) {
|
||||
//20100716 - 603.8
|
||||
game.getState().setValue(this.getSourceId().toString() + "triggered", Boolean.TRUE);
|
||||
super.trigger(game, controllerId);
|
||||
super.trigger(game, controllerId, triggeringEvent);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -79,10 +79,10 @@ class LurkingJackalsStateTriggeredAbility extends StateTriggeredAbility {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void trigger(Game game, UUID controllerId) {
|
||||
public void trigger(Game game, UUID controllerId, GameEvent triggeringEvent) {
|
||||
//20100716 - 603.8
|
||||
game.getState().setValue(this.getSourceId().toString() + "triggered", Boolean.TRUE);
|
||||
super.trigger(game, controllerId);
|
||||
super.trigger(game, controllerId, triggeringEvent);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -75,10 +75,10 @@ class OpalAvengerStateTriggeredAbility extends StateTriggeredAbility {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void trigger(Game game, UUID controllerId) {
|
||||
public void trigger(Game game, UUID controllerId, GameEvent triggeringEvent) {
|
||||
//20100716 - 603.8
|
||||
game.getState().setValue(this.getSourceId().toString() + "triggered", Boolean.TRUE);
|
||||
super.trigger(game, controllerId);
|
||||
super.trigger(game, controllerId, triggeringEvent);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
84
Mage.Sets/src/mage/cards/s/StrictProctor.java
Normal file
84
Mage.Sets/src/mage/cards/s/StrictProctor.java
Normal file
|
@ -0,0 +1,84 @@
|
|||
package mage.cards.s;
|
||||
|
||||
import mage.MageInt;
|
||||
import mage.abilities.TriggeredAbilityImpl;
|
||||
import mage.abilities.costs.mana.GenericManaCost;
|
||||
import mage.abilities.effects.common.CounterUnlessPaysEffect;
|
||||
import mage.abilities.keyword.FlyingAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Zone;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.target.targetpointer.FixedTarget;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class StrictProctor extends CardImpl {
|
||||
|
||||
public StrictProctor(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}");
|
||||
|
||||
this.subtype.add(SubType.SPIRIT);
|
||||
this.subtype.add(SubType.CLERIC);
|
||||
this.power = new MageInt(1);
|
||||
this.toughness = new MageInt(3);
|
||||
|
||||
// Flying
|
||||
this.addAbility(FlyingAbility.getInstance());
|
||||
|
||||
// Whenever a permanent entering the battlefield causes a triggered ability to trigger, counter that ability unless its controller pays {2}.
|
||||
this.addAbility(new StrictProctorTriggeredAbility());
|
||||
}
|
||||
|
||||
private StrictProctor(final StrictProctor card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public StrictProctor copy() {
|
||||
return new StrictProctor(this);
|
||||
}
|
||||
}
|
||||
|
||||
class StrictProctorTriggeredAbility extends TriggeredAbilityImpl {
|
||||
|
||||
StrictProctorTriggeredAbility() {
|
||||
super(Zone.BATTLEFIELD, new CounterUnlessPaysEffect(new GenericManaCost(2)));
|
||||
}
|
||||
|
||||
private StrictProctorTriggeredAbility(final StrictProctorTriggeredAbility ability) {
|
||||
super(ability);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkEventType(GameEvent event, Game game) {
|
||||
return event.getType() == GameEvent.EventType.ABILITY_TRIGGERED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
GameEvent triggeringEvent = (GameEvent) game.getState().getValue(event.getId().toString());
|
||||
if (triggeringEvent == null || triggeringEvent.getType() != GameEvent.EventType.ENTERS_THE_BATTLEFIELD) {
|
||||
return false;
|
||||
}
|
||||
getEffects().setTargetPointer(new FixedTarget(triggeringEvent.getTargetId(), game));
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StrictProctorTriggeredAbility copy() {
|
||||
return new StrictProctorTriggeredAbility(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRule() {
|
||||
return "Whenever a permanent entering the battlefield causes a triggered ability to trigger, " +
|
||||
"counter that ability unless its controller pays {2}.";
|
||||
}
|
||||
}
|
|
@ -80,10 +80,10 @@ class VeiledCrocodileStateTriggeredAbility extends StateTriggeredAbility {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void trigger(Game game, UUID controllerId) {
|
||||
public void trigger(Game game, UUID controllerId, GameEvent triggeringEvent) {
|
||||
//20100716 - 603.8
|
||||
game.getState().setValue(this.getSourceId().toString() + "triggered", Boolean.TRUE);
|
||||
super.trigger(game, controllerId);
|
||||
super.trigger(game, controllerId, triggeringEvent);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -269,6 +269,7 @@ public final class StrixhavenSchoolOfMages extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Stonebound Mentor", 239, Rarity.COMMON, mage.cards.s.StoneboundMentor.class));
|
||||
cards.add(new SetCardInfo("Stonerise Spirit", 32, Rarity.COMMON, mage.cards.s.StoneriseSpirit.class));
|
||||
cards.add(new SetCardInfo("Storm-Kiln Artist", 115, Rarity.UNCOMMON, mage.cards.s.StormKilnArtist.class));
|
||||
cards.add(new SetCardInfo("Strict Proctor", 33, Rarity.RARE, mage.cards.s.StrictProctor.class));
|
||||
cards.add(new SetCardInfo("Strixhaven Stadium", 259, Rarity.RARE, mage.cards.s.StrixhavenStadium.class));
|
||||
cards.add(new SetCardInfo("Study Break", 34, Rarity.COMMON, mage.cards.s.StudyBreak.class));
|
||||
cards.add(new SetCardInfo("Sudden Breakthrough", 116, Rarity.COMMON, mage.cards.s.SuddenBreakthrough.class));
|
||||
|
|
|
@ -48,7 +48,7 @@ public interface Ability extends Controllable, Serializable {
|
|||
*
|
||||
* @see mage.players.PlayerImpl#playAbility(mage.abilities.ActivatedAbility,
|
||||
* mage.game.Game)
|
||||
* @see mage.game.GameImpl#addTriggeredAbility(mage.abilities.TriggeredAbility)
|
||||
* @see Game#addTriggeredAbility(TriggeredAbility, GameEvent)
|
||||
* @see mage.game.GameImpl#addDelayedTriggeredAbility(mage.abilities.DelayedTriggeredAbility)
|
||||
*/
|
||||
void newId();
|
||||
|
@ -58,7 +58,7 @@ public interface Ability extends Controllable, Serializable {
|
|||
*
|
||||
* @see mage.players.PlayerImpl#playAbility(mage.abilities.ActivatedAbility,
|
||||
* mage.game.Game)
|
||||
* @see mage.game.GameImpl#addTriggeredAbility(mage.abilities.TriggeredAbility)
|
||||
* @see Game#addTriggeredAbility(TriggeredAbility, GameEvent)
|
||||
* @see mage.game.GameImpl#addDelayedTriggeredAbility(mage.abilities.DelayedTriggeredAbility)
|
||||
*/
|
||||
void newOriginalId();
|
||||
|
|
|
@ -37,7 +37,7 @@ public class DelayedTriggeredAbilities extends AbilitiesImpl<DelayedTriggeredAbi
|
|||
continue;
|
||||
}
|
||||
if (ability.checkTrigger(event, game)) {
|
||||
ability.trigger(game, ability.controllerId);
|
||||
ability.trigger(game, ability.controllerId, event);
|
||||
if (ability.getTriggerOnlyOnce()) {
|
||||
it.remove();
|
||||
}
|
||||
|
|
|
@ -31,10 +31,10 @@ public abstract class StateTriggeredAbility extends TriggeredAbilityImpl {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void trigger(Game game, UUID controllerId) {
|
||||
public void trigger(Game game, UUID controllerId, GameEvent triggeringEvent) {
|
||||
//20100716 - 603.8
|
||||
game.getState().setValue(this.getSourceId().toString() + "triggered", Boolean.TRUE);
|
||||
super.trigger(game, controllerId);
|
||||
super.trigger(game, controllerId, triggeringEvent);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -95,7 +95,7 @@ public class TriggeredAbilities extends ConcurrentHashMap<String, TriggeredAbili
|
|||
NumberOfTriggersEvent numberOfTriggersEvent = new NumberOfTriggersEvent(ability, event);
|
||||
if (!game.replaceEvent(numberOfTriggersEvent)) {
|
||||
for (int i = 0; i < numberOfTriggersEvent.getAmount(); i++) {
|
||||
ability.trigger(game, ability.getControllerId());
|
||||
ability.trigger(game, ability.getControllerId(), event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ import java.util.UUID;
|
|||
*/
|
||||
public interface TriggeredAbility extends Ability {
|
||||
|
||||
void trigger(Game game, UUID controllerId);
|
||||
void trigger(Game game, UUID controllerId, GameEvent event);
|
||||
|
||||
/**
|
||||
* This check for the relevant event types is called at first to prevent
|
||||
|
@ -52,4 +52,7 @@ public interface TriggeredAbility extends Ability {
|
|||
@Override
|
||||
TriggeredAbility copy();
|
||||
|
||||
void setTriggerEvent(GameEvent event);
|
||||
|
||||
GameEvent getTriggerEvent();
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ public abstract class TriggeredAbilityImpl extends AbilityImpl implements Trigge
|
|||
protected boolean optional;
|
||||
protected boolean leavesTheBattlefieldTrigger;
|
||||
private boolean triggersOnce = false;
|
||||
private GameEvent triggerEvent = null;
|
||||
|
||||
public TriggeredAbilityImpl(Zone zone, Effect effect) {
|
||||
this(zone, effect, false);
|
||||
|
@ -53,15 +54,15 @@ public abstract class TriggeredAbilityImpl extends AbilityImpl implements Trigge
|
|||
}
|
||||
|
||||
@Override
|
||||
public void trigger(Game game, UUID controllerId) {
|
||||
public void trigger(Game game, UUID controllerId, GameEvent triggeringEvent) {
|
||||
//20091005 - 603.4
|
||||
if (checkInterveningIfClause(game)) {
|
||||
addthing(game);
|
||||
game.addTriggeredAbility(this);
|
||||
setLastTrigger(game);
|
||||
game.addTriggeredAbility(this, triggeringEvent);
|
||||
}
|
||||
}
|
||||
|
||||
private final void addthing(Game game) {
|
||||
private final void setLastTrigger(Game game) {
|
||||
if (!triggersOnce) {
|
||||
return;
|
||||
}
|
||||
|
@ -70,6 +71,16 @@ public abstract class TriggeredAbilityImpl extends AbilityImpl implements Trigge
|
|||
), game.getTurnNum());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTriggerEvent(GameEvent triggerEvent) {
|
||||
this.triggerEvent = triggerEvent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GameEvent getTriggerEvent() {
|
||||
return triggerEvent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkTriggeredAlready(Game game) {
|
||||
if (!triggersOnce) {
|
||||
|
|
|
@ -11,6 +11,7 @@ import mage.constants.SubType;
|
|||
import mage.filter.FilterCard;
|
||||
import mage.filter.predicate.mageobject.ConvertedManaCostPredicate;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.target.common.TargetCardInYourGraveyard;
|
||||
|
||||
import java.util.UUID;
|
||||
|
@ -46,14 +47,14 @@ public class SoulshiftAbility extends DiesSourceTriggeredAbility {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void trigger(Game game, UUID controllerId) {
|
||||
public void trigger(Game game, UUID controllerId, GameEvent triggeringEvent) {
|
||||
this.getTargets().clear();
|
||||
int intValue = amount.calculate(game, this, null);
|
||||
FilterCard filter = new FilterCard("Spirit card with converted mana cost " + intValue + " or less from your graveyard");
|
||||
filter.add(new ConvertedManaCostPredicate(ComparisonType.FEWER_THAN, intValue + 1));
|
||||
filter.add(SubType.SPIRIT.getPredicate());
|
||||
this.addTarget(new TargetCardInYourGraveyard(filter));
|
||||
super.trigger(game, controllerId); //To change body of generated methods, choose Tools | Templates.
|
||||
super.trigger(game, controllerId, triggeringEvent); //To change body of generated methods, choose Tools | Templates.
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -421,7 +421,7 @@ public interface Game extends MageItem, Serializable {
|
|||
|
||||
Card copyCard(Card cardToCopy, Ability source, UUID newController);
|
||||
|
||||
void addTriggeredAbility(TriggeredAbility ability);
|
||||
void addTriggeredAbility(TriggeredAbility ability, GameEvent triggeringEvent);
|
||||
|
||||
UUID addDelayedTriggeredAbility(DelayedTriggeredAbility delayedAbility);
|
||||
|
||||
|
|
|
@ -1742,9 +1742,10 @@ public abstract class GameImpl implements Game, Serializable {
|
|||
* For internal use only
|
||||
*
|
||||
* @param ability
|
||||
* @param triggeringEvent
|
||||
*/
|
||||
@Override
|
||||
public void addTriggeredAbility(TriggeredAbility ability) {
|
||||
public void addTriggeredAbility(TriggeredAbility ability, GameEvent triggeringEvent) {
|
||||
if (ability.getControllerId() == null) {
|
||||
String sourceName = "no sourceId";
|
||||
if (ability.getSourceId() != null) {
|
||||
|
@ -1770,6 +1771,7 @@ public abstract class GameImpl implements Game, Serializable {
|
|||
if (newAbility.getSourceObjectZoneChangeCounter() == 0) {
|
||||
newAbility.setSourceObjectZoneChangeCounter(getState().getZoneChangeCounter(ability.getSourceId()));
|
||||
}
|
||||
newAbility.setTriggerEvent(triggeringEvent);
|
||||
state.addTriggeredAbility(newAbility);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -188,6 +188,7 @@ public class GameEvent implements Serializable {
|
|||
playerId player that tries to use this ability
|
||||
*/
|
||||
TRIGGERED_ABILITY,
|
||||
ABILITY_TRIGGERED,
|
||||
RESOLVING_ABILITY,
|
||||
/* COPY_STACKOBJECT
|
||||
targetId id of the spell/ability to copy
|
||||
|
|
|
@ -780,7 +780,7 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
Cards toDiscard = new CardsImpl();
|
||||
Cards hand = getHand().copy();
|
||||
for (int i = 0; i < amount; i++) {
|
||||
if(hand.isEmpty()){
|
||||
if (hand.isEmpty()) {
|
||||
break;
|
||||
}
|
||||
Card card = hand.getRandom(game);
|
||||
|
@ -1496,6 +1496,7 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
if (sourceObject != null) {
|
||||
sourceObject.adjustTargets(ability, game);
|
||||
}
|
||||
UUID triggerId = null;
|
||||
if (ability.canChooseTarget(game, playerId)) {
|
||||
if (ability.isUsesStack()) {
|
||||
game.getStack().push(new StackAbility(ability, playerId));
|
||||
|
@ -1509,14 +1510,23 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
if (!ability.isUsesStack()) {
|
||||
ability.resolve(game);
|
||||
} else {
|
||||
game.fireEvent(new GameEvent(GameEvent.EventType.TRIGGERED_ABILITY,
|
||||
ability.getId(), ability, ability.getControllerId()));
|
||||
game.fireEvent(new GameEvent(
|
||||
GameEvent.EventType.TRIGGERED_ABILITY,
|
||||
ability.getId(), ability, ability.getControllerId()
|
||||
));
|
||||
triggerId = ability.getId();
|
||||
}
|
||||
game.removeBookmark(bookmark);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
restoreState(bookmark, triggeredAbility.getRule(), game); // why restore is needed here? (to remove the triggered ability from the stack because of no possible targets)
|
||||
GameEvent event = new GameEvent(
|
||||
GameEvent.EventType.ABILITY_TRIGGERED,
|
||||
triggerId, ability, ability.getControllerId()
|
||||
);
|
||||
game.getState().setValue(event.getId().toString(), ability.getTriggerEvent());
|
||||
game.fireEvent(event);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue