Merge branch 'master' into 'm19'

This commit is contained in:
Rob Schnautz
2018-06-29 15:40:15 +00:00
6 changed files with 107 additions and 43 deletions

View File

@@ -76,6 +76,51 @@ public final class CardFacePredicates {
};
}
static class ValidPredicate implements Predicate<ICardFace> {
private String valid;
public ValidPredicate(final String valid) {
this.valid = valid;
}
@Override
public boolean apply(ICardFace input) {
String k[] = valid.split("\\.", 2);
if ("Card".equals(k[0])) {
// okay
} else if ("Permanent".equals(k[0])) {
if (input.getType().isInstant() || input.getType().isSorcery()) {
return false;
}
} else if (!input.getType().hasStringType(k[0])) {
return false;
}
if (k.length > 1) {
for (final String m : k[1].split("\\+")) {
if (!hasProperty(input, m)) {
return false;
}
}
}
return true;
}
static protected boolean hasProperty(ICardFace input, final String v) {
if (v.startsWith("non")) {
return !hasProperty(input, v.substring(3));
} else if (!input.getType().hasStringType(v)) {
return false;
}
return true;
}
}
public static Predicate<ICardFace> valid(final String val) {
return new ValidPredicate(val);
}
public static class Presets {
/** The Constant isBasicLand. */
public static final Predicate<ICardFace> IS_BASIC_LAND = new Predicate<ICardFace>() {

View File

@@ -368,6 +368,7 @@ public class GameAction {
final Map<String, Object> runParams = Maps.newHashMap();
runParams.put("Card", lastKnownInfo);
runParams.put("Cause", cause);
runParams.put("Origin", zoneFrom != null ? zoneFrom.getZoneType().name() : null);
runParams.put("Destination", zoneTo.getZoneType().name());
runParams.put("SpellAbilityStackInstance", game.stack.peek());

View File

@@ -105,17 +105,8 @@ public class ChooseCardNameEffect extends SpellAbilityEffect {
final String message = validDesc.equals("card") ? "Name a card" : "Name a " + validDesc + " card.";
Predicate<ICardFace> cpp = Predicates.alwaysTrue();
if ( StringUtils.containsIgnoreCase(valid, "nonland") ) {
cpp = CardFacePredicates.Presets.IS_NON_LAND;
}
if ( StringUtils.containsIgnoreCase(valid, "nonbasic") ) {
cpp = Predicates.not(CardFacePredicates.Presets.IS_BASIC_LAND);
}
if ( StringUtils.containsIgnoreCase(valid, "noncreature") ) {
cpp = Predicates.not(CardFacePredicates.Presets.IS_CREATURE);
} else if ( StringUtils.containsIgnoreCase(valid, "creature") ) {
cpp = CardFacePredicates.Presets.IS_CREATURE;
if (sa.hasParam("ValidCards")) {
cpp = CardFacePredicates.valid(valid);
}
chosen = p.getController().chooseCardName(sa, cpp, valid, message);

View File

@@ -65,57 +65,68 @@ public class TriggerChangesZone extends Trigger {
/** {@inheritDoc} */
@Override
public final boolean performTest(final java.util.Map<String, Object> runParams2) {
if (this.mapParams.containsKey("Origin")) {
if (!this.mapParams.get("Origin").equals("Any")) {
if (this.mapParams.get("Origin") == null) {
public final boolean performTest(final Map<String, Object> runParams2) {
if (hasParam("Origin")) {
if (!getParam("Origin").equals("Any")) {
if (getParam("Origin") == null) {
return false;
}
if (!ArrayUtils.contains(
this.mapParams.get("Origin").split(","), runParams2.get("Origin")
getParam("Origin").split(","), runParams2.get("Origin")
)) {
return false;
}
}
}
if (this.mapParams.containsKey("Destination")) {
if (!this.mapParams.get("Destination").equals("Any")) {
if (hasParam("Destination")) {
if (!getParam("Destination").equals("Any")) {
if (!ArrayUtils.contains(
this.mapParams.get("Destination").split(","), runParams2.get("Destination")
getParam("Destination").split(","), runParams2.get("Destination")
)) {
return false;
}
}
}
if (this.mapParams.containsKey("ExcludedDestinations")) {
if (hasParam("ExcludedDestinations")) {
if (!ArrayUtils.contains(
this.mapParams.get("ExcludedDestinations").split(","), runParams2.get("Destination")
getParam("ExcludedDestinations").split(","), runParams2.get("Destination")
)) {
return false;
}
}
if (this.mapParams.containsKey("ValidCard")) {
if (hasParam("ValidCard")) {
Card moved = (Card) runParams2.get("Card");
final Game game = this.getHostCard().getGame();
boolean isDiesTrig = "Battlefield".equals(this.mapParams.get("Origin"))
&& "Graveyard".equals(this.mapParams.get("Destination"));
final Game game = getHostCard().getGame();
boolean isDiesTrig = "Battlefield".equals(getParam("Origin"))
&& "Graveyard".equals(getParam("Destination"));
if (isDiesTrig) {
moved = game.getChangeZoneLKIInfo(moved);
}
if (!moved.isValid(this.mapParams.get("ValidCard").split(","), this.getHostCard().getController(),
this.getHostCard(), null)) {
if (!moved.isValid(getParam("ValidCard").split(","), getHostCard().getController(),
getHostCard(), null)) {
return false;
}
}
if (hasParam("ValidCause")) {
if (!runParams2.containsKey("Cause") ) {
return false;
}
SpellAbility cause = (SpellAbility) runParams2.get("Cause");
if (!cause.getHostCard().isValid(getParam("ValidCause").split(","), getHostCard().getController(),
getHostCard(), null)) {
return false;
}
}
// Check number of lands ETB this turn on triggered card's controller
if (mapParams.containsKey("CheckOnTriggeredCard")) {
final String[] condition = mapParams.get("CheckOnTriggeredCard").split(" ", 2);
if (hasParam("CheckOnTriggeredCard")) {
final String[] condition = getParam("CheckOnTriggeredCard").split(" ", 2);
final Card host = hostCard.getGame().getCardState(hostCard);
final String comparator = condition.length < 2 ? "GE1" : condition[1];
@@ -128,8 +139,8 @@ public class TriggerChangesZone extends Trigger {
}
// Check amount of damage dealt to the triggered card
if (this.mapParams.containsKey("DamageReceivedCondition")) {
final String cond = this.mapParams.get("DamageReceivedCondition");
if (hasParam("DamageReceivedCondition")) {
final String cond = getParam("DamageReceivedCondition");
if (cond.length() < 3) {
return false;
}
@@ -152,7 +163,7 @@ public class TriggerChangesZone extends Trigger {
}
}
if (this.mapParams.containsKey("OncePerEffect")) {
if (hasParam("OncePerEffect")) {
// A "once per effect" trigger will only trigger once regardless of how many things the effect caused
// to change zones.
@@ -184,8 +195,8 @@ public class TriggerChangesZone extends Trigger {
}
/* this trigger can only be activated once per turn, verify it hasn't already run */
if (this.mapParams.containsKey("ActivationLimit")) {
return this.getActivationsThisTurn() < Integer.parseInt(this.mapParams.get("ActivationLimit"));
if (hasParam("ActivationLimit")) {
return this.getActivationsThisTurn() < Integer.parseInt(getParam("ActivationLimit"));
}
return true;

View File

@@ -13,6 +13,7 @@ import javax.swing.WindowConstants;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import forge.card.CardStateName;
import org.apache.commons.lang3.StringUtils;
import com.google.common.base.Function;
@@ -165,7 +166,25 @@ public class GuiChoose {
if (paper == null) {
paper = FModel.getMagicDb().getVariantCards().getUniqueByName(face.getName());
}
matchUI.setCard(paper);
if (paper != null && !paper.getName().equals(face.getName())) {
Card c = Card.getCardForUi(paper);
boolean foundState = false;
for (CardStateName cs : c.getStates()) {
if (c.getState(cs).getName().equals(face.getName())) {
foundState = true;
c.setState(cs, true);
matchUI.setCard(c.getView());
break;
}
}
if (!foundState) {
matchUI.setCard(paper);
}
} else {
matchUI.setCard(paper);
}
return;
}

View File

@@ -1,11 +1,8 @@
Name:Vivien's Invocation
ManaCost:5 G G
Types:Sorcery
A:SP$ PeekAndReveal | Cost$ 4 G G | PeekAmount$ 7 | RememberPeeked$ True | SubAbility$ DBChangeZone | OptionalDecider$ You | Look at the top seven cards of your library. You may put a creature card from among them onto the battlefield. Put the rest on the bottom of your library in a random order. When a creature is put onto the battlefield this way, it deals damage equal to its power to target creature an opponent controls.
SVar:DBEffect:DB$ Effect | Name$ Vivien's Invocation Effect | Triggers$ EffTModeChangesZone | RememberObjects$ Remembered.Creature | SVars$ EffTrigDealDamage,EffX | Description$ When a creature is put onto the battlefield this way, it deals damage equal to its power to target creature an opponent controls. | SubAbility$ DBChangeZone
SVar:DBChangeZone:DB$ ChangeZone | Origin$ Library | NoLooking$ True | Destination$ Battlefield | LimitSearchLibrary$ Creature.IsRemembered | ChangeValid$ Creature.IsRemembered | Controller$ You | WithoutManaCost$ True | Amount$ 1 | SubAbility$ DBRestRandomOrder
SVar:DBRestRandomOrder:DB$ ChangeZone | Defined$ Remembered | AtRandom$ True | Origin$ Library | Destination$ Library | LibraryPosition$ -1
SVar:EffTModeChangesZone:Mode$ ChangesZone | ValidCard$ Remembered.Creature | TriggerZones$ Stack | Origin$ Library | Destination$ Battlefield | SubAbility$ EffTrigDealDamage | TriggerDescription$ When a creature is put onto the battlefield this way, it deals damage equal to its power to target creature an opponent controls.
SVar:EffTrigDealDamage:DB$ DealDamage | ValidSource$ Remembered+inZoneBattlefield | ValidTgts$ Creature.OppCtrl | TgtPrompt$ Select target creature an opponent controls | NumDmg$ EffX | References$ EffX
SVar:EffX:RememberedCard$CardPower
Oracle:Look at the top seven cards of your library. You may put a creature card from among them onto the battlefield. Put the rest on the bottom of your library in a random order. When a creature is put onto the battlefield this way, it deals damage equal to its power to target creature an opponent controls.
A:SP$ Dig | Cost$ 5 G G | DigNum$ 7 | ChangeNum$ 1 | ChangeValid$ Creature | Optional$ True | RestRandomOrder$ True | DestinationZone$ Battlefield | ForceRevealToController$ True | SpellDescription$ Look at the top seven cards of your library. You may put a creature card from among them onto the battlefield. Put the rest on the bottom of your library in a random order. When a creature is put onto the battlefield this way, it deals damage equals to its power to target creature an opponent controls.
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Creature | ValidCause$ Card.Self | Execute$ DBDealDamage | Secondary$ True | TriggerDescription$ When a creature is put onto the battlefield this way, it deals damage equals to its power to target creature an opponent controls.
SVar:DBDealDamage:DB$ DealDamage | ValidTgts$ Creature.OppCtrl | AILogic$ PowerDmg | TgtPrompt$ Select target creature an opponent controls | NumDmg$ X | References$ X | DamageSource$ TriggeredCard
SVar:X:TriggeredCard$CardPower
Oracle:Look at the top seven cards of your library. You may put a creature card from among them onto the battlefield. Put the rest on the bottom of your library in a random order. When a creature is put onto the battlefield this way, it deals damage equals to its power to target creature an opponent controls.