mirror of
https://github.com/magefree/mage.git
synced 2025-12-27 14:02:05 -08:00
* Added 28 cards from Vintage Masters.
This commit is contained in:
parent
b0a822184b
commit
d84076ba40
70 changed files with 3926 additions and 63 deletions
|
|
@ -28,26 +28,26 @@
|
|||
|
||||
package mage.abilities.effects.common;
|
||||
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.Mode;
|
||||
import mage.abilities.effects.ReplacementEffectImpl;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.events.GameEvent.EventType;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.Mode;
|
||||
import mage.abilities.effects.ReplacementEffectImpl;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.events.GameEvent.EventType;
|
||||
import mage.game.permanent.Permanent;
|
||||
|
||||
/**
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
public class SkipNextUntapTargetEffect extends ReplacementEffectImpl {
|
||||
|
||||
protected Set<UUID> usedFor = new HashSet<UUID>();
|
||||
protected Set<UUID> usedFor = new HashSet<>();
|
||||
protected int count;
|
||||
|
||||
public SkipNextUntapTargetEffect() {
|
||||
|
|
@ -79,15 +79,10 @@ public class SkipNextUntapTargetEffect extends ReplacementEffectImpl {
|
|||
|
||||
@Override
|
||||
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
|
||||
if (targetPointer.getTargets(game, source).size() < 2) {
|
||||
used = true;
|
||||
} else {
|
||||
count++;
|
||||
}
|
||||
// not clear how to turn off the effect for more than one target
|
||||
// especially as some targets may leave the battlefield since the effect creation
|
||||
// so handling this in applies method is the only option for now for such cases
|
||||
if (count == targetPointer.getTargets(game, source).size()) {
|
||||
if (usedFor.size() >= targetPointer.getTargets(game, source).size()) {
|
||||
// this won't work for targets disappeared before applies() return true
|
||||
used = true;
|
||||
}
|
||||
|
|
@ -97,17 +92,19 @@ public class SkipNextUntapTargetEffect extends ReplacementEffectImpl {
|
|||
@Override
|
||||
public boolean applies(GameEvent event, Ability source, Game game) {
|
||||
if (game.getTurn().getStepType() == PhaseStep.UNTAP && event.getType() == EventType.UNTAP) {
|
||||
for (UUID target : targetPointer.getTargets(game, source)) {
|
||||
if (event.getTargetId().equals(target)) {
|
||||
if (!usedFor.contains(target)) {
|
||||
usedFor.add(target);
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
if (targetPointer.getTargets(game, source).contains(event.getTargetId())
|
||||
&& !usedFor.contains(event.getTargetId())) {
|
||||
Permanent permanent = game.getPermanent(event.getTargetId());
|
||||
if (permanent == null) {
|
||||
usedFor.add(event.getTargetId());
|
||||
return false;
|
||||
}
|
||||
if (permanent.getControllerId().equals(game.getActivePlayerId())) {
|
||||
usedFor.add(event.getTargetId());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -77,6 +77,9 @@ public class BlocksIfAbleTargetEffect extends RequirementEffect {
|
|||
|
||||
@Override
|
||||
public String getText(Mode mode) {
|
||||
if (staticText != null && !staticText.isEmpty()) {
|
||||
return staticText;
|
||||
}
|
||||
if (this.duration == Duration.EndOfTurn) {
|
||||
return "Target " + mode.getTargets().get(0).getTargetName() + " blocks this turn if able";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
|
||||
package mage.abilities.effects.common.continious;
|
||||
|
||||
import java.util.Locale;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.Layer;
|
||||
import mage.constants.Outcome;
|
||||
|
|
@ -41,6 +42,8 @@ import mage.target.Target;
|
|||
|
||||
import java.util.UUID;
|
||||
import mage.cards.Card;
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.game.turn.Step;
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
@ -52,6 +55,11 @@ public class GainAbilityTargetEffect extends ContinuousEffectImpl {
|
|||
// shall a card gain the ability (otherwise permanent)
|
||||
private boolean onCard;
|
||||
|
||||
// Duration until next phase step of player
|
||||
private PhaseStep durationPhaseStep = null;
|
||||
private UUID durationPlayerId;
|
||||
private boolean sameStep;
|
||||
|
||||
public GainAbilityTargetEffect(Ability ability, Duration duration) {
|
||||
this(ability, duration, null);
|
||||
}
|
||||
|
|
@ -72,6 +80,41 @@ public class GainAbilityTargetEffect extends ContinuousEffectImpl {
|
|||
super(effect);
|
||||
this.ability = effect.ability.copy();
|
||||
this.onCard = effect.onCard;
|
||||
this.durationPhaseStep = effect.durationPhaseStep;
|
||||
this.durationPlayerId = effect.durationPlayerId;
|
||||
this.sameStep = effect.sameStep;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to set a duration to the next durationPhaseStep of the
|
||||
* first controller of the effect.
|
||||
*
|
||||
* @param phaseStep
|
||||
*/
|
||||
public void setDurationToPhase(PhaseStep phaseStep) {
|
||||
durationPhaseStep = phaseStep;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Ability source, Game game) {
|
||||
super.init(source, game);
|
||||
if (durationPhaseStep != null) {
|
||||
durationPlayerId = source.getControllerId();
|
||||
sameStep = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInactive(Ability source, Game game) {
|
||||
if (durationPhaseStep != null && durationPhaseStep.equals(game.getPhase().getStep().getType()))
|
||||
{
|
||||
if (!sameStep && game.getActivePlayerId().equals(durationPlayerId) || game.getPlayer(durationPlayerId).hasReachedNextTurnAfterLeaving()) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
sameStep = false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -127,7 +170,12 @@ public class GainAbilityTargetEffect extends ContinuousEffectImpl {
|
|||
sb.append(target.getTargetName()).append(" gains ");
|
||||
|
||||
}
|
||||
sb.append(ability.getRule()).append(" ").append(duration.toString());
|
||||
if (durationPhaseStep != null) {
|
||||
sb.append(" until your next ").append(durationPhaseStep.toString().toLowerCase(Locale.ENGLISH));
|
||||
}
|
||||
if (!duration.toString().isEmpty()) {
|
||||
sb.append(ability.getRule()).append(" ").append(duration.toString());
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,15 +1,15 @@
|
|||
package mage.abilities.keyword;
|
||||
|
||||
import java.io.ObjectStreamException;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.EvasionAbility;
|
||||
import mage.abilities.MageSingleton;
|
||||
import mage.abilities.effects.RestrictionEffect;
|
||||
import mage.constants.AsThoughEffectType;
|
||||
import mage.constants.Duration;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
|
||||
import java.io.ObjectStreamException;
|
||||
|
||||
/**
|
||||
* "Shadow" keyword
|
||||
* @author Loki
|
||||
|
|
@ -61,8 +61,10 @@ class ShadowEffect extends RestrictionEffect implements MageSingleton {
|
|||
|
||||
@Override
|
||||
public boolean canBeBlocked(Permanent attacker, Permanent blocker, Ability source, Game game) {
|
||||
if (blocker.getAbilities().containsKey(ShadowAbility.getInstance().getId()))
|
||||
if (blocker.getAbilities().containsKey(ShadowAbility.getInstance().getId())
|
||||
|| game.getContinuousEffects().asThough(blocker.getId(), AsThoughEffectType.BLOCK_SHADOW, blocker.getControllerId(), game)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ public enum AsThoughEffectType {
|
|||
ATTACK,
|
||||
ACTIVATE_HASTE,
|
||||
BLOCK_TAPPED,
|
||||
BLOCK_SHADOW,
|
||||
BE_BLOCKED,
|
||||
CAST,
|
||||
DAMAGE,
|
||||
|
|
|
|||
|
|
@ -28,9 +28,8 @@
|
|||
|
||||
package mage.game.permanent.token;
|
||||
|
||||
import mage.constants.CardType;
|
||||
import mage.MageInt;
|
||||
import mage.ObjectColor;
|
||||
import mage.constants.CardType;
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
@ -39,9 +38,14 @@ import mage.ObjectColor;
|
|||
public class InsectToken extends Token {
|
||||
|
||||
public InsectToken() {
|
||||
this("M10");
|
||||
}
|
||||
|
||||
public InsectToken(String setCode) {
|
||||
super("Insect", "1/1 green Insect creature token");
|
||||
setOriginalExpansionSetCode(setCode);
|
||||
cardType.add(CardType.CREATURE);
|
||||
color = ObjectColor.GREEN;
|
||||
color.setGreen(true);
|
||||
subtype.add("Insect");
|
||||
power = new MageInt(1);
|
||||
toughness = new MageInt(1);
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ public abstract class Step implements Serializable {
|
|||
stepPart = StepPart.PRE;
|
||||
}
|
||||
|
||||
public void priority(Game game, UUID activePlayerId, boolean resuming) {
|
||||
public void priority(Game game, UUID activePlayerId, boolean resuming) {
|
||||
if (hasPriority) {
|
||||
stepPart = StepPart.PRIORITY;
|
||||
game.playPriority(activePlayerId, resuming);
|
||||
|
|
|
|||
|
|
@ -123,7 +123,7 @@ public class Turn implements Serializable {
|
|||
resetCounts();
|
||||
game.getPlayer(activePlayerId).beginTurn(game);
|
||||
for (Phase phase: phases) {
|
||||
if (game.isPaused() || game.gameOver(null)) {
|
||||
if (game.isPaused() || game.gameOver(null)) {
|
||||
return;
|
||||
}
|
||||
currentPhase = phase;
|
||||
|
|
|
|||
|
|
@ -68,14 +68,19 @@ public class TargetCardInHand extends TargetCard {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean canTarget(UUID id, Ability source, Game game) {
|
||||
Card card = game.getPlayer(source.getControllerId()).getHand().get(id, game);
|
||||
public boolean canTarget(UUID id, UUID playerId, Ability source, Game game) {
|
||||
Card card = game.getPlayer(playerId).getHand().get(id, game);
|
||||
if (card != null) {
|
||||
return filter.match(card, source.getControllerId(), game);
|
||||
return filter.match(card, source.getSourceId(), playerId, game);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canTarget(UUID id, Ability source, Game game) {
|
||||
return this.canTarget(id, source.getControllerId(), source, game);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<UUID> possibleTargets(UUID sourceId, UUID playerId, Game game) {
|
||||
Set<UUID> possibleTargets = new HashSet<>();
|
||||
|
|
|
|||
|
|
@ -44,6 +44,10 @@ public class TargetControlledCreaturePermanent extends TargetControlledPermanent
|
|||
this(numTargets, numTargets, new FilterControlledCreaturePermanent(), false);
|
||||
}
|
||||
|
||||
public TargetControlledCreaturePermanent(FilterControlledCreaturePermanent filter) {
|
||||
super(1, 1, filter, false);
|
||||
}
|
||||
|
||||
public TargetControlledCreaturePermanent(int minNumTargets, int maxNumTargets, FilterControlledCreaturePermanent filter, boolean notTarget) {
|
||||
super(minNumTargets, maxNumTargets, filter, notTarget);
|
||||
this.targetName = filter.getMessage();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue