mirror of
https://github.com/magefree/mage.git
synced 2025-12-25 04:52:07 -08:00
Merge remote-tracking branch 'origin/master'
# Conflicts: # Mage.Sets/src/mage/sets/gatecrash/Hindervines.java # Mage.Sets/src/mage/sets/timeshifted/Darkness.java
This commit is contained in:
commit
6cf04e9bd2
82 changed files with 5563 additions and 402 deletions
|
|
@ -27,10 +27,10 @@
|
|||
*/
|
||||
package mage.abilities.common.delayed;
|
||||
|
||||
import mage.constants.TargetController;
|
||||
import mage.abilities.DelayedTriggeredAbility;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.TargetController;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.events.GameEvent.EventType;
|
||||
|
|
@ -44,9 +44,10 @@ public class AtTheBeginOfMainPhaseDelayedTriggeredAbility extends DelayedTrigger
|
|||
|
||||
public enum PhaseSelection {
|
||||
|
||||
NEXT_PRECOMBAT_MAIN("next precombat"),
|
||||
NEXT_POSTCOMAT_MAIN("next postcombat"),
|
||||
NEXT_MAIN("next");
|
||||
NEXT_PRECOMBAT_MAIN("next precombat main phase"),
|
||||
NEXT_POSTCOMAT_MAIN("next postcombat main phase"),
|
||||
NEXT_MAIN("next main phase"),
|
||||
NEXT_MAIN_THIS_TURN("next main phase this turn");
|
||||
|
||||
private final String text;
|
||||
|
||||
|
|
@ -63,7 +64,6 @@ public class AtTheBeginOfMainPhaseDelayedTriggeredAbility extends DelayedTrigger
|
|||
private final TargetController targetController;
|
||||
private final PhaseSelection phaseSelection;
|
||||
|
||||
|
||||
public AtTheBeginOfMainPhaseDelayedTriggeredAbility(Effect effect, boolean optional, TargetController targetController, PhaseSelection phaseSelection) {
|
||||
super(effect, Duration.EndOfGame, true, optional);
|
||||
this.targetController = targetController;
|
||||
|
|
@ -116,6 +116,7 @@ public class AtTheBeginOfMainPhaseDelayedTriggeredAbility extends DelayedTrigger
|
|||
private boolean checkPhase(EventType eventType) {
|
||||
switch (phaseSelection) {
|
||||
case NEXT_MAIN:
|
||||
case NEXT_MAIN_THIS_TURN:
|
||||
return EventType.PRECOMBAT_MAIN_PHASE_PRE.equals(eventType) || EventType.POSTCOMBAT_MAIN_PHASE_PRE.equals(eventType);
|
||||
case NEXT_POSTCOMAT_MAIN:
|
||||
return EventType.POSTCOMBAT_MAIN_PHASE_PRE.equals(eventType);
|
||||
|
|
@ -131,16 +132,16 @@ public class AtTheBeginOfMainPhaseDelayedTriggeredAbility extends DelayedTrigger
|
|||
StringBuilder sb = new StringBuilder();
|
||||
switch (targetController) {
|
||||
case YOU:
|
||||
sb.append("At the beginning of your ").append(phaseSelection.toString()).append(" main phase, ");
|
||||
sb.append("At the beginning of your ").append(phaseSelection.toString()).append(", ");
|
||||
break;
|
||||
case OPPONENT:
|
||||
sb.append("At the beginning of an opponent's ").append(phaseSelection.toString()).append(" main phase, ");
|
||||
sb.append("At the beginning of an opponent's ").append(phaseSelection.toString()).append(", ");
|
||||
break;
|
||||
case ANY:
|
||||
sb.append("At the beginning of the ").append(phaseSelection.toString()).append(" main phase, ");
|
||||
sb.append("At the beginning of the ").append(phaseSelection.toString()).append(", ");
|
||||
break;
|
||||
case CONTROLLER_ATTACHED_TO:
|
||||
sb.append("At the beginning of the ").append(phaseSelection.toString()).append(" main phase of enchanted creature's controller, ");
|
||||
sb.append("At the beginning of the ").append(phaseSelection.toString()).append(" of enchanted creature's controller, ");
|
||||
break;
|
||||
}
|
||||
sb.append(getEffects().getText(modes.getMode()));
|
||||
|
|
|
|||
|
|
@ -0,0 +1,29 @@
|
|||
package mage.abilities.condition.common;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.condition.Condition;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Quercitron
|
||||
*/
|
||||
public class AttachedCondition implements Condition {
|
||||
|
||||
private static final AttachedCondition fInstance = new AttachedCondition();
|
||||
|
||||
public static AttachedCondition getInstance() {
|
||||
return fInstance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Permanent attachment = game.getPermanent(source.getSourceId());
|
||||
if (attachment == null || attachment.getAttachedTo() == null) {
|
||||
return false;
|
||||
}
|
||||
Permanent attachedTo = game.getPermanent(attachment.getAttachedTo());
|
||||
return (attachedTo != null);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
package mage.abilities.condition.common;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.condition.Condition;
|
||||
import mage.constants.WatcherScope;
|
||||
import mage.game.Game;
|
||||
import mage.watchers.Watcher;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Quercitron
|
||||
*/
|
||||
public class WatcherCondition implements Condition {
|
||||
|
||||
private final String watcherKey;
|
||||
private final WatcherScope watcherScope;
|
||||
private final String text;
|
||||
|
||||
public WatcherCondition(String watcherKey, WatcherScope watcherScope) {
|
||||
this(watcherKey, watcherScope, "");
|
||||
}
|
||||
|
||||
public WatcherCondition(String watcherKey, WatcherScope watcherScope, String text) {
|
||||
this.watcherKey = watcherKey;
|
||||
this.watcherScope = watcherScope;
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Watcher watcher = null;
|
||||
switch (watcherScope) {
|
||||
case GAME:
|
||||
watcher = game.getState().getWatchers().get(watcherKey);
|
||||
break;
|
||||
case PLAYER:
|
||||
watcher = game.getState().getWatchers().get(watcherKey, source.getControllerId());
|
||||
break;
|
||||
case CARD:
|
||||
watcher = game.getState().getWatchers().get(watcherKey, source.getSourceId());
|
||||
break;
|
||||
}
|
||||
return watcher != null && watcher.conditionMet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return text;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -2,7 +2,7 @@ package mage.abilities.dynamicvalue.common;
|
|||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.costs.Cost;
|
||||
import mage.abilities.costs.common.DiscardCardCost;
|
||||
import mage.abilities.costs.common.DiscardTargetCost;
|
||||
import mage.abilities.dynamicvalue.DynamicValue;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.cards.Card;
|
||||
|
|
@ -16,8 +16,8 @@ public class DiscardCostCardConvertedMana implements DynamicValue {
|
|||
@Override
|
||||
public int calculate(Game game, Ability sourceAbility, Effect effect) {
|
||||
for (Cost cost : sourceAbility.getCosts()) {
|
||||
if (cost instanceof DiscardCardCost) {
|
||||
DiscardCardCost discardCost = (DiscardCardCost) cost;
|
||||
if (cost instanceof DiscardTargetCost) {
|
||||
DiscardTargetCost discardCost = (DiscardTargetCost) cost;
|
||||
int cmc = 0;
|
||||
for (Card card : discardCost.getCards()) {
|
||||
cmc += card.getConvertedManaCost();
|
||||
|
|
|
|||
|
|
@ -72,6 +72,8 @@ public abstract class CopySpellForEachItCouldTargetEffect<T extends MageItem> ex
|
|||
|
||||
protected abstract Spell getSpell(Game game, Ability source);
|
||||
|
||||
protected abstract Player getPlayer(Game game, Ability source);
|
||||
|
||||
protected abstract boolean changeTarget(Target target, Game game, Ability source);
|
||||
|
||||
protected abstract void modifyCopy(Spell copy, Game game, Ability source);
|
||||
|
|
@ -82,8 +84,8 @@ public abstract class CopySpellForEachItCouldTargetEffect<T extends MageItem> ex
|
|||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (controller == null) {
|
||||
Player actingPlayer = getPlayer(game, source);
|
||||
if (actingPlayer == null) {
|
||||
return false;
|
||||
}
|
||||
Spell spell = getSpell(game, source);
|
||||
|
|
@ -111,7 +113,7 @@ public abstract class CopySpellForEachItCouldTargetEffect<T extends MageItem> ex
|
|||
sampleTarget.setNotTarget(true);
|
||||
|
||||
Map<UUID, Map<UUID, Spell>> playerTargetCopyMap = new HashMap<>();
|
||||
for (UUID objId : sampleTarget.possibleTargets(controller.getId(), game)) {
|
||||
for (UUID objId : sampleTarget.possibleTargets(actingPlayer.getId(), game)) {
|
||||
MageItem obj = game.getObject(objId);
|
||||
if (obj == null) {
|
||||
obj = game.getPlayer(objId);
|
||||
|
|
@ -131,7 +133,7 @@ public abstract class CopySpellForEachItCouldTargetEffect<T extends MageItem> ex
|
|||
for (TargetAddress addr : targetsToBeChanged) {
|
||||
// potential target must be legal for all targets that we're about to change
|
||||
Target targetInstance = addr.getTarget(copy);
|
||||
legal &= targetInstance.canTarget(objId, addr.getSpellAbility(copy), game);
|
||||
legal &= targetInstance.canTarget(actingPlayer.getId(), objId, addr.getSpellAbility(copy), game);
|
||||
if (!legal) {
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
package mage.util;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
import mage.abilities.Mode;
|
||||
import mage.abilities.Modes;
|
||||
|
|
@ -59,6 +60,7 @@ public class TargetAddress {
|
|||
this.card = card;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<TargetAddress> iterator() {
|
||||
return new TargetAddressIterator(card);
|
||||
}
|
||||
|
|
@ -87,10 +89,12 @@ public class TargetAddress {
|
|||
calcNext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return lastTargetIndex != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TargetAddress next() {
|
||||
TargetAddress ret = new TargetAddress(lastSpellAbilityIndex,
|
||||
lastMode,
|
||||
|
|
@ -100,6 +104,7 @@ public class TargetAddress {
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
|
@ -188,4 +193,25 @@ public class TargetAddress {
|
|||
public int hashCode() {
|
||||
return spellAbilityIndex ^ mode.hashCode() ^ targetIndex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
final TargetAddress other = (TargetAddress) obj;
|
||||
if (this.spellAbilityIndex != other.spellAbilityIndex) {
|
||||
return false;
|
||||
}
|
||||
if (this.targetIndex != other.targetIndex) {
|
||||
return false;
|
||||
}
|
||||
return Objects.equals(this.mode, other.mode);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue