mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-16 02:38:02 +00:00
- Basic AI for AF Learn
- Some minor tweaks and fixes for AF Learn
This commit is contained in:
committed by
Michael Kamensky
parent
5b77205b77
commit
0627d37f69
@@ -32,6 +32,7 @@ import com.google.common.collect.Lists;
|
|||||||
|
|
||||||
import forge.ai.ability.ChangeZoneAi;
|
import forge.ai.ability.ChangeZoneAi;
|
||||||
import forge.ai.ability.ExploreAi;
|
import forge.ai.ability.ExploreAi;
|
||||||
|
import forge.ai.ability.LearnAi;
|
||||||
import forge.ai.simulation.SpellAbilityPicker;
|
import forge.ai.simulation.SpellAbilityPicker;
|
||||||
import forge.card.MagicColor;
|
import forge.card.MagicColor;
|
||||||
import forge.card.mana.ManaCost;
|
import forge.card.mana.ManaCost;
|
||||||
@@ -2095,8 +2096,11 @@ public class AiController {
|
|||||||
if (useSimulation) {
|
if (useSimulation) {
|
||||||
return simPicker.chooseCardToHiddenOriginChangeZone(destination, origin, sa, fetchList, player2, decider);
|
return simPicker.chooseCardToHiddenOriginChangeZone(destination, origin, sa, fetchList, player2, decider);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sa.getApi() == ApiType.Explore) {
|
if (sa.getApi() == ApiType.Explore) {
|
||||||
return ExploreAi.shouldPutInGraveyard(fetchList, decider);
|
return ExploreAi.shouldPutInGraveyard(fetchList, decider);
|
||||||
|
} else if (sa.getApi() == ApiType.Learn) {
|
||||||
|
return LearnAi.chooseCardToLearn(fetchList, decider, sa);
|
||||||
} else {
|
} else {
|
||||||
return ChangeZoneAi.chooseCardToHiddenOriginChangeZone(destination, origin, sa, fetchList, player2, decider);
|
return ChangeZoneAi.chooseCardToHiddenOriginChangeZone(destination, origin, sa, fetchList, player2, decider);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -95,6 +95,7 @@ public enum SpellApiToAi {
|
|||||||
.put(ApiType.Haunt, HauntAi.class)
|
.put(ApiType.Haunt, HauntAi.class)
|
||||||
.put(ApiType.ImmediateTrigger, ImmediateTriggerAi.class)
|
.put(ApiType.ImmediateTrigger, ImmediateTriggerAi.class)
|
||||||
.put(ApiType.Investigate, InvestigateAi.class)
|
.put(ApiType.Investigate, InvestigateAi.class)
|
||||||
|
.put(ApiType.Learn, LearnAi.class)
|
||||||
.put(ApiType.LoseLife, LifeLoseAi.class)
|
.put(ApiType.LoseLife, LifeLoseAi.class)
|
||||||
.put(ApiType.LosesGame, GameLossAi.class)
|
.put(ApiType.LosesGame, GameLossAi.class)
|
||||||
.put(ApiType.Mana, ManaEffectAi.class)
|
.put(ApiType.Mana, ManaEffectAi.class)
|
||||||
|
|||||||
56
forge-ai/src/main/java/forge/ai/ability/LearnAi.java
Normal file
56
forge-ai/src/main/java/forge/ai/ability/LearnAi.java
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
package forge.ai.ability;
|
||||||
|
|
||||||
|
|
||||||
|
import forge.ai.ComputerUtilCard;
|
||||||
|
import forge.ai.PlayerControllerAi;
|
||||||
|
import forge.ai.SpellAbilityAi;
|
||||||
|
import forge.game.card.Card;
|
||||||
|
import forge.game.card.CardCollection;
|
||||||
|
import forge.game.card.CardLists;
|
||||||
|
import forge.game.card.CardPredicates;
|
||||||
|
import forge.game.player.Player;
|
||||||
|
import forge.game.player.PlayerActionConfirmMode;
|
||||||
|
import forge.game.spellability.SpellAbility;
|
||||||
|
import forge.game.zone.ZoneType;
|
||||||
|
|
||||||
|
public class LearnAi extends SpellAbilityAi {
|
||||||
|
@Override
|
||||||
|
protected boolean canPlayAI(Player aiPlayer, SpellAbility sa) {
|
||||||
|
// For the time being, Learn is treated as universally positive due to being optional
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean doTriggerAINoCost(Player aiPlayer, SpellAbility sa, boolean mandatory) {
|
||||||
|
return mandatory || canPlayAI(aiPlayer, sa);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean chkAIDrawback(SpellAbility sa, Player aiPlayer) {
|
||||||
|
return canPlayAI(aiPlayer, sa);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean confirmAction(Player player, SpellAbility sa, PlayerActionConfirmMode mode, String message) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Card chooseCardToLearn(CardCollection options, Player ai, SpellAbility sa) {
|
||||||
|
CardCollection sideboard = CardLists.filter(options, CardPredicates.inZone(ZoneType.Sideboard));
|
||||||
|
CardCollection hand = CardLists.filter(options, CardPredicates.inZone(ZoneType.Hand));
|
||||||
|
hand.remove(sa.getHostCard()); // this card will be used in the process, don't consider it for discard
|
||||||
|
|
||||||
|
CardCollection lessons = CardLists.filter(sideboard, CardPredicates.isType("Lesson"));
|
||||||
|
CardCollection goodDiscards = ((PlayerControllerAi)ai.getController()).getAi().getCardsToDiscard(1, 1, hand, sa);
|
||||||
|
|
||||||
|
if (!lessons.isEmpty()) {
|
||||||
|
return ComputerUtilCard.getBestAI(lessons);
|
||||||
|
} else if (!goodDiscards.isEmpty()) {
|
||||||
|
return ComputerUtilCard.getWorstAI(goodDiscards);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Don't choose anything if there's no good option
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -11,6 +11,7 @@ import forge.ai.ComputerUtilAbility;
|
|||||||
import forge.ai.ComputerUtilCost;
|
import forge.ai.ComputerUtilCost;
|
||||||
import forge.ai.ability.ChangeZoneAi;
|
import forge.ai.ability.ChangeZoneAi;
|
||||||
import forge.ai.ability.ExploreAi;
|
import forge.ai.ability.ExploreAi;
|
||||||
|
import forge.ai.ability.LearnAi;
|
||||||
import forge.ai.simulation.GameStateEvaluator.Score;
|
import forge.ai.simulation.GameStateEvaluator.Score;
|
||||||
import forge.game.Game;
|
import forge.game.Game;
|
||||||
import forge.game.ability.ApiType;
|
import forge.game.ability.ApiType;
|
||||||
@@ -423,6 +424,8 @@ public class SpellAbilityPicker {
|
|||||||
}
|
}
|
||||||
if (sa.getApi() == ApiType.Explore) {
|
if (sa.getApi() == ApiType.Explore) {
|
||||||
return ExploreAi.shouldPutInGraveyard(fetchList, decider);
|
return ExploreAi.shouldPutInGraveyard(fetchList, decider);
|
||||||
|
} else if (sa.getApi() == ApiType.Learn) {
|
||||||
|
return LearnAi.chooseCardToLearn(fetchList, decider, sa);
|
||||||
} else {
|
} else {
|
||||||
return ChangeZoneAi.chooseCardToHiddenOriginChangeZone(destination, origin, sa, fetchList, player2, decider);
|
return ChangeZoneAi.chooseCardToHiddenOriginChangeZone(destination, origin, sa, fetchList, player2, decider);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -134,7 +134,7 @@ public class GameFormat implements Comparable<GameFormat> {
|
|||||||
if (!this.allowedSetCodes_ro.isEmpty()) {
|
if (!this.allowedSetCodes_ro.isEmpty()) {
|
||||||
p = Predicates.and(p, printed ?
|
p = Predicates.and(p, printed ?
|
||||||
IPaperCard.Predicates.printedInSets(this.allowedSetCodes_ro, printed) :
|
IPaperCard.Predicates.printedInSets(this.allowedSetCodes_ro, printed) :
|
||||||
(Predicate<PaperCard>)(StaticData.instance().getCommonCards().wasPrintedInSets(this.allowedSetCodes_ro)));
|
StaticData.instance().getCommonCards().wasPrintedInSets(this.allowedSetCodes_ro));
|
||||||
}
|
}
|
||||||
if (!this.allowedRarities.isEmpty()) {
|
if (!this.allowedRarities.isEmpty()) {
|
||||||
List<Predicate<? super PaperCard>> crp = Lists.newArrayList();
|
List<Predicate<? super PaperCard>> crp = Lists.newArrayList();
|
||||||
|
|||||||
@@ -93,6 +93,7 @@ public enum ApiType {
|
|||||||
Haunt (HauntEffect.class),
|
Haunt (HauntEffect.class),
|
||||||
Investigate (InvestigateEffect.class),
|
Investigate (InvestigateEffect.class),
|
||||||
ImmediateTrigger (ImmediateTriggerEffect.class),
|
ImmediateTrigger (ImmediateTriggerEffect.class),
|
||||||
|
Learn (LearnEffect.class),
|
||||||
LookAt (LookAtEffect.class),
|
LookAt (LookAtEffect.class),
|
||||||
LoseLife (LifeLoseEffect.class),
|
LoseLife (LifeLoseEffect.class),
|
||||||
LosesGame (GameLossEffect.class),
|
LosesGame (GameLossEffect.class),
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import java.util.Arrays;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.ObjectUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
import com.google.common.base.Predicate;
|
import com.google.common.base.Predicate;
|
||||||
@@ -942,6 +943,12 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// for Wish cards, if the player is controlled by someone else
|
||||||
|
// they can't fetch from the outside the game/sideboard
|
||||||
|
if (player.isControlled()) {
|
||||||
|
origin.remove(ZoneType.Sideboard);
|
||||||
|
}
|
||||||
|
|
||||||
CardCollection fetchList;
|
CardCollection fetchList;
|
||||||
boolean shuffleMandatory = true;
|
boolean shuffleMandatory = true;
|
||||||
boolean searchedLibrary = false;
|
boolean searchedLibrary = false;
|
||||||
@@ -1179,6 +1186,9 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean combatChanged = false;
|
||||||
|
final CardZoneTable triggerList = new CardZoneTable();
|
||||||
|
|
||||||
for (Player player : HiddenOriginChoicesMap.keySet()) {
|
for (Player player : HiddenOriginChoicesMap.keySet()) {
|
||||||
boolean searchedLibrary = HiddenOriginChoicesMap.get(player).searchedLibrary;
|
boolean searchedLibrary = HiddenOriginChoicesMap.get(player).searchedLibrary;
|
||||||
boolean shuffleMandatory = HiddenOriginChoicesMap.get(player).shuffleMandatory;
|
boolean shuffleMandatory = HiddenOriginChoicesMap.get(player).shuffleMandatory;
|
||||||
@@ -1188,12 +1198,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
|||||||
ZoneType destination = HiddenOriginChoicesMap.get(player).destination;
|
ZoneType destination = HiddenOriginChoicesMap.get(player).destination;
|
||||||
CardCollection movedCards = new CardCollection();
|
CardCollection movedCards = new CardCollection();
|
||||||
long ts = game.getNextTimestamp();
|
long ts = game.getNextTimestamp();
|
||||||
final CardZoneTable triggerList = new CardZoneTable();
|
Player decider = ObjectUtils.firstNonNull(chooser, player);
|
||||||
boolean combatChanged = false;
|
|
||||||
Player decider = chooser;
|
|
||||||
if (decider == null) {
|
|
||||||
decider = player;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (final Card c : chosenCards) {
|
for (final Card c : chosenCards) {
|
||||||
Card movedCard = null;
|
Card movedCard = null;
|
||||||
@@ -1423,15 +1428,15 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
|||||||
registerDelayedTrigger(sa, sa.getParam("AtEOT"), movedCards);
|
registerDelayedTrigger(sa, sa.getParam("AtEOT"), movedCards);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (combatChanged) {
|
}
|
||||||
game.updateCombatForView();
|
if (combatChanged) {
|
||||||
game.fireEvent(new GameEventCombatChanged());
|
game.updateCombatForView();
|
||||||
}
|
game.fireEvent(new GameEventCombatChanged());
|
||||||
triggerList.triggerChangesZoneAll(game);
|
}
|
||||||
|
triggerList.triggerChangesZoneAll(game);
|
||||||
|
|
||||||
if (sa.hasParam("UntilHostLeavesPlay")) {
|
if (sa.hasParam("UntilHostLeavesPlay")) {
|
||||||
source.addLeavesPlayCommand(untilHostLeavesPlayCommand(triggerList, source));
|
source.addLeavesPlayCommand(untilHostLeavesPlayCommand(triggerList, source));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package forge.game.ability.effects;
|
||||||
|
|
||||||
|
import forge.game.Game;
|
||||||
|
import forge.game.ability.SpellAbilityEffect;
|
||||||
|
import forge.game.card.Card;
|
||||||
|
import forge.game.card.CardZoneTable;
|
||||||
|
import forge.game.player.Player;
|
||||||
|
import forge.game.spellability.SpellAbility;
|
||||||
|
|
||||||
|
public class LearnEffect extends SpellAbilityEffect {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getStackDescription(SpellAbility sa) {
|
||||||
|
return "Learn. (You may reveal a Lesson card you own from outside the game and put it into your hand, or discard a card to draw a card.)";
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void resolve(SpellAbility sa) {
|
||||||
|
final Card source = sa.getHostCard();
|
||||||
|
final Game game = source.getGame();
|
||||||
|
CardZoneTable table = new CardZoneTable();
|
||||||
|
for (Player p : getTargetPlayers(sa)) {
|
||||||
|
p.learnLesson(sa, table);
|
||||||
|
}
|
||||||
|
table.triggerChangesZoneAll(game);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -2667,6 +2667,11 @@ public class Player extends GameEntity implements Comparable<Player> {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final boolean isControlled() {
|
||||||
|
Player ctrlPlayer = this.getControllingPlayer();
|
||||||
|
return ctrlPlayer != null && ctrlPlayer != this;
|
||||||
|
}
|
||||||
|
|
||||||
public void addController(long timestamp, Player pl) {
|
public void addController(long timestamp, Player pl) {
|
||||||
final IGameEntitiesFactory master = (IGameEntitiesFactory)pl.getLobbyPlayer();
|
final IGameEntitiesFactory master = (IGameEntitiesFactory)pl.getLobbyPlayer();
|
||||||
addController(timestamp, pl, master.createMindSlaveController(pl, this), true);
|
addController(timestamp, pl, master.createMindSlaveController(pl, this), true);
|
||||||
@@ -3604,4 +3609,49 @@ public class Player extends GameEntity implements Comparable<Player> {
|
|||||||
game.getAction().revealTo(revealCards, otherPlayers, Localizer.getInstance().getMessage("lblRevealFaceDownCards"));
|
game.getAction().revealTo(revealCards, otherPlayers, Localizer.getInstance().getMessage("lblRevealFaceDownCards"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void learnLesson(SpellAbility sa, CardZoneTable table) {
|
||||||
|
// Replacement effects
|
||||||
|
Map<AbilityKey, Object> repParams = AbilityKey.mapFromAffected(this);
|
||||||
|
repParams.put(AbilityKey.Cause, sa);
|
||||||
|
if (game.getReplacementHandler().run(ReplacementType.Learn, repParams) != ReplacementResult.NotReplaced) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
CardCollection list = new CardCollection();
|
||||||
|
if (!isControlled()) {
|
||||||
|
list.addAll(CardLists.getType(getZone(ZoneType.Sideboard), "Lesson"));
|
||||||
|
}
|
||||||
|
list.addAll(getZone(ZoneType.Hand));
|
||||||
|
if (list.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Card c = getController().chooseSingleCardForZoneChange(ZoneType.Hand, ImmutableList.of(ZoneType.Sideboard, ZoneType.Hand),
|
||||||
|
sa, list, null, "Learn a Lesson", true, this);
|
||||||
|
if (c == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (c.isInZone(ZoneType.Sideboard)) { // Sideboard Lesson to Hand
|
||||||
|
Card moved = game.getAction().moveTo(ZoneType.Hand, c, sa);
|
||||||
|
table.put(ZoneType.Sideboard, ZoneType.Hand, moved);
|
||||||
|
} else if (c.isInZone(ZoneType.Hand)) { // Discard and Draw
|
||||||
|
boolean firstDiscard = getNumDiscardedThisTurn() == 0;
|
||||||
|
if (discard(c, sa, table) != null) {
|
||||||
|
// Change this if something would make multiple player learn at the same time
|
||||||
|
|
||||||
|
// Discard Trigger outside Effect
|
||||||
|
final Map<AbilityKey, Object> runParams = AbilityKey.newMap();
|
||||||
|
runParams.put(AbilityKey.Player, this);
|
||||||
|
runParams.put(AbilityKey.Cards, new CardCollection(c));
|
||||||
|
runParams.put(AbilityKey.Cause, sa);
|
||||||
|
runParams.put(AbilityKey.FirstTime, firstDiscard);
|
||||||
|
getGame().getTriggerHandler().runTrigger(TriggerType.DiscardedAll, runParams, false);
|
||||||
|
|
||||||
|
for (Card d : drawCards(1, sa)) {
|
||||||
|
table.put(ZoneType.Library, ZoneType.Hand, d); // does a ChangesZoneAll care about moving from Library to Hand
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -485,6 +485,8 @@ public class PlayerView extends GameEntityView {
|
|||||||
return TrackableProperty.Library;
|
return TrackableProperty.Library;
|
||||||
case Flashback:
|
case Flashback:
|
||||||
return TrackableProperty.Flashback;
|
return TrackableProperty.Flashback;
|
||||||
|
case Sideboard:
|
||||||
|
return TrackableProperty.Sideboard;
|
||||||
default:
|
default:
|
||||||
return null; //other zones not represented
|
return null; //other zones not represented
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* Forge: Play Magic: the Gathering.
|
||||||
|
* Copyright (C) 2011 Forge Team
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package forge.game.replacement;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import forge.game.ability.AbilityKey;
|
||||||
|
import forge.game.card.Card;
|
||||||
|
import forge.game.spellability.SpellAbility;
|
||||||
|
|
||||||
|
public class ReplaceLearn extends ReplacementEffect {
|
||||||
|
|
||||||
|
public ReplaceLearn(Map<String, String> map, Card host, boolean intrinsic) {
|
||||||
|
super(map, host, intrinsic);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see forge.card.replacement.ReplacementEffect#canReplace(java.util.HashMap)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean canReplace(Map<AbilityKey, Object> runParams) {
|
||||||
|
if (!matchesValidParam("ValidPlayer", runParams.get(AbilityKey.Affected))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see forge.card.replacement.ReplacementEffect#setReplacingObjects(java.util.HashMap, forge.card.spellability.SpellAbility)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void setReplacingObjects(Map<AbilityKey, Object> runParams, SpellAbility sa) {
|
||||||
|
sa.setReplacingObject(AbilityKey.Player, runParams.get(AbilityKey.Affected));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -28,6 +28,7 @@ public enum ReplacementType {
|
|||||||
DrawCards(ReplaceDrawCards.class),
|
DrawCards(ReplaceDrawCards.class),
|
||||||
GainLife(ReplaceGainLife.class),
|
GainLife(ReplaceGainLife.class),
|
||||||
GameLoss(ReplaceGameLoss.class),
|
GameLoss(ReplaceGameLoss.class),
|
||||||
|
Learn(ReplaceLearn.class),
|
||||||
Mill(ReplaceMill.class),
|
Mill(ReplaceMill.class),
|
||||||
Moved(ReplaceMoved.class),
|
Moved(ReplaceMoved.class),
|
||||||
ProduceMana(ReplaceProduceMana.class),
|
ProduceMana(ReplaceProduceMana.class),
|
||||||
|
|||||||
@@ -171,6 +171,7 @@ public enum TrackableProperty {
|
|||||||
Graveyard(TrackableTypes.CardViewCollectionType, FreezeMode.IgnoresFreeze),
|
Graveyard(TrackableTypes.CardViewCollectionType, FreezeMode.IgnoresFreeze),
|
||||||
Hand(TrackableTypes.CardViewCollectionType, FreezeMode.IgnoresFreeze),
|
Hand(TrackableTypes.CardViewCollectionType, FreezeMode.IgnoresFreeze),
|
||||||
Library(TrackableTypes.CardViewCollectionType, FreezeMode.IgnoresFreeze),
|
Library(TrackableTypes.CardViewCollectionType, FreezeMode.IgnoresFreeze),
|
||||||
|
Sideboard(TrackableTypes.CardViewCollectionType, FreezeMode.IgnoresFreeze),
|
||||||
Mana(TrackableTypes.ManaMapType, FreezeMode.IgnoresFreeze),
|
Mana(TrackableTypes.ManaMapType, FreezeMode.IgnoresFreeze),
|
||||||
IsExtraTurn(TrackableTypes.BooleanType),
|
IsExtraTurn(TrackableTypes.BooleanType),
|
||||||
ExtraTurnCount(TrackableTypes.IntegerType),
|
ExtraTurnCount(TrackableTypes.IntegerType),
|
||||||
|
|||||||
@@ -484,6 +484,7 @@ public final class CMatchUI
|
|||||||
case Exile:
|
case Exile:
|
||||||
case Flashback:
|
case Flashback:
|
||||||
case Command:
|
case Command:
|
||||||
|
case Sideboard:
|
||||||
if (FloatingZone.show(this,player,zone)) {
|
if (FloatingZone.show(this,player,zone)) {
|
||||||
updatedPlayerZones.add(update);
|
updatedPlayerZones.add(update);
|
||||||
}
|
}
|
||||||
|
|||||||
7
forge-gui/res/cardsfolder/upcoming/academic_dispute.txt
Normal file
7
forge-gui/res/cardsfolder/upcoming/academic_dispute.txt
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
Name:Academic Dispute
|
||||||
|
ManaCost:R
|
||||||
|
Types:Instant
|
||||||
|
A:SP$ Pump | ValidTgts$ Creature | TgtPrompt$ Select target creature | KW$ HIDDEN CARDNAME blocks each combat if able. | SubAbility$ DBPump | StackDescription$ SpellDescription | SpellDescription$ Target creature blocks this turn if able.
|
||||||
|
SVar:DBPump:DB$ Pump | Defined$ Targeted | KW$ Reach | OptionQuestion$ Do you want TARGETS to gain reach? | SubAbility$ DBLearn | StackDescription$ SpellDescription | SpellDescription$ You may have it gain reach until end of turn.
|
||||||
|
SVar:DBLearn:DB$ Learn | SpellDescription$ Learn. (You may reveal a Lesson card you own from outside the game and put it into your hand, or discard a card to draw a card.)
|
||||||
|
Oracle:Target creature blocks this turn if able. You may have it gain reach until end of turn.\nLearn. (You may reveal a Lesson card you own from outside the game and put it into your hand, or discard a card to draw a card.)
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
Name:Arcane Subtraction
|
||||||
|
ManaCost:1 U
|
||||||
|
Types:Instant
|
||||||
|
A:SP$ Pump | ValidTgts$ Creature | TgtPrompt$ Select target creature | NumAtt$ -4 | IsCurse$ True | SubAbility$ DBLearn | SpellDescription$ Target creature gets -4/-0 until end of turn.
|
||||||
|
SVar:DBLearn:DB$ Learn | SpellDescription$ Learn. (You may reveal a Lesson card you own from outside the game and put it into your hand, or discard a card to draw a card.)
|
||||||
|
Oracle:Target creature gets -4/-0 until end of turn.\nLearn. (You may reveal a Lesson card you own from outside the game and put it into your hand, or discard a card to draw a card.)
|
||||||
7
forge-gui/res/cardsfolder/upcoming/cram_session.txt
Normal file
7
forge-gui/res/cardsfolder/upcoming/cram_session.txt
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
Name:Cram Session
|
||||||
|
ManaCost:1 BG
|
||||||
|
Types:Sorcery
|
||||||
|
A:SP$ GainLife | LifeAmount$ 4 | Defined$ You | SubAbility$ DBLearn | SpellDescription$ You gain 4 life.
|
||||||
|
SVar:DBLearn:DB$ Learn | SpellDescription$ Learn. (You may reveal a Lesson card you own from outside the game and put it into your hand, or discard a card to draw a card.)
|
||||||
|
DeckHas:Ability$LifeGain
|
||||||
|
Oracle:You gain 4 life.\nLearn. (You may reveal a Lesson card you own from outside the game and put it into your hand, or discard a card to draw a card.)
|
||||||
6
forge-gui/res/cardsfolder/upcoming/divide_by_zero.txt
Normal file
6
forge-gui/res/cardsfolder/upcoming/divide_by_zero.txt
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
Name:Divide by Zero
|
||||||
|
ManaCost:2 U
|
||||||
|
Types:Instant
|
||||||
|
A:SP$ ChangeZone | ValidTgts$ Permanent.cmcGE1,Card.inZoneStack+cmcGE1 | TgtZone$ Stack,Battlefield | Origin$ Battlefield,Stack | Fizzle$ True | Destination$ Hand | SubAbility$ DBLearn | SpellDescription$ Return target spell or permanent with mana value 1 or greater to its owner’s hand.
|
||||||
|
SVar:DBLearn:DB$ Learn | SpellDescription$ Learn. (You may reveal a Lesson card you own from outside the game and put it into your hand, or discard a card to draw a card.)
|
||||||
|
Oracle:Return target spell or permanent with mana value 1 or greater to its owner’s hand.\nLearn. (You may reveal a Lesson card you own from outside the game and put it into your hand, or discard a card to draw a card.)
|
||||||
11
forge-gui/res/cardsfolder/upcoming/dream_strix.txt
Normal file
11
forge-gui/res/cardsfolder/upcoming/dream_strix.txt
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
Name:Dream Strix
|
||||||
|
ManaCost:2 U
|
||||||
|
Types:Creature Bird Ilusion
|
||||||
|
PT:2/2
|
||||||
|
K:Flying
|
||||||
|
T:Mode$ BecomesTarget | ValidTarget$ Card.Self | SourceType$ Spell | TriggerZones$ Battlefield | Execute$ TrigSac | TriggerDescription$ When CARDNAME becomes the target of a spell, sacrifice it.
|
||||||
|
SVar:TrigSac:DB$ Sacrifice | ValidCard$ Card.Self
|
||||||
|
T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Card.Self | Execute$ TrigLearn | TriggerDescription$ When CARDNAME dies, learn. (You may reveal a Lesson card you own from outside the game and put it into your hand, or discard a card to draw a card.)
|
||||||
|
SVar:TrigLearn:DB$ Learn
|
||||||
|
DeckHas:Ability$Sacrifice
|
||||||
|
Oracle:Flying\nWhen Dream Strix becomes the target of a spell, sacrifice it.\nWhen Dream Strix dies, learn. (You may reveal a Lesson card you own from outside the game and put it into your hand, or discard a card to draw a card.)
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
Name:Enthusiastic Study
|
||||||
|
ManaCost:2 R
|
||||||
|
Types:Instant
|
||||||
|
A:SP$ Pump | ValidTgts$ Creature | TgtPrompt$ Select target creature | NumAtt$ +3 | NumDef$ +1 | KW$ Trample | SubAbility$ DBLearn | SpellDescription$ Target creature gets +3/+1 and gains trample until end of turn.
|
||||||
|
SVar:DBLearn:DB$ Learn | SpellDescription$ Learn. (You may reveal a Lesson card you own from outside the game and put it into your hand, or discard a card to draw a card.)
|
||||||
|
Oracle:Target creature gets +3/+1 and gains trample until end of turn.\nLearn. (You may reveal a Lesson card you own from outside the game and put it into your hand, or discard a card to draw a card.)
|
||||||
9
forge-gui/res/cardsfolder/upcoming/eyetwitch.txt
Normal file
9
forge-gui/res/cardsfolder/upcoming/eyetwitch.txt
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
Name:Eyetwitch
|
||||||
|
ManaCost:B
|
||||||
|
Types:Creature Eye Bat
|
||||||
|
PT:1/1
|
||||||
|
K:Flying
|
||||||
|
T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Card.Self | Execute$ TrigLearn | TriggerDescription$ When CARDNAME dies, learn. (You may reveal a Lesson card you own from outside the game and put it into your hand, or discard a card to draw a card.)
|
||||||
|
SVar:TrigLearn:DB$ Learn
|
||||||
|
SVar:SacMe:1
|
||||||
|
Oracle:Flying\nWhen Eyetwitch dies, learn. (You may reveal a Lesson card you own from outside the game and put it into your hand, or discard a card to draw a card.)
|
||||||
6
forge-gui/res/cardsfolder/upcoming/field_trip.txt
Normal file
6
forge-gui/res/cardsfolder/upcoming/field_trip.txt
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
Name:Field Trip
|
||||||
|
ManaCost:2 G
|
||||||
|
Types:Sorcery
|
||||||
|
A:SP$ ChangeZone | Origin$ Library | Destination$ Battlefield | Tapped$ True | ChangeType$ Land.Forest+Basic | ChangeNum$ 1 | SubAbility$ DBLearn | SpellDescription$ Search your library for a basic Forest card, put that card onto the battlefield tapped, then shuffle.
|
||||||
|
SVar:DBLearn:DB$ Learn | SpellDescription$ Learn. (You may reveal a Lesson card you own from outside the game and put it into your hand, or discard a card to draw a card.)
|
||||||
|
Oracle:Search your library for a basic Forest card, put that card onto the battlefield tapped, then shuffle.\nLearn. (You may reveal a Lesson card you own from outside the game and put it into your hand, or discard a card to draw a card.)
|
||||||
10
forge-gui/res/cardsfolder/upcoming/first_day_of_class.txt
Normal file
10
forge-gui/res/cardsfolder/upcoming/first_day_of_class.txt
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
Name:First Day of Class
|
||||||
|
ManaCost:1 R
|
||||||
|
Types:Instant
|
||||||
|
A:SP$ Effect | Triggers$ CreatureETB | SubAbility$ DBLearn | SpellDescription$ Whenever a creature enters the battlefield under your control this turn, put a +1/+1 counter on it and it gains haste until end of turn.
|
||||||
|
SVar:CreatureETB:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Creature.YouCtrl | TriggerZones$ Command | Execute$ TrigPutCounter | TriggerDescription$ Whenever a creature enters the battlefield under your control this turn, put a +1/+1 counter on it and it gains haste until end of turn.
|
||||||
|
SVar:TrigPutCounter:DB$ PutCounter | Defined$ TriggeredCardLKICopy | CounterType$ P1P1 | SubAbility$ DBPump
|
||||||
|
SVar:DBPump:DB$ Pump | Defined$ TriggeredCard | KW$ Haste
|
||||||
|
SVar:DBLearn:DB$ Learn | SpellDescription$ Learn. (You may reveal a Lesson card you own from outside the game and put it into your hand, or discard a card to draw a card.)
|
||||||
|
DeckHas:Ability$Counters
|
||||||
|
Oracle:Whenever a creature enters the battlefield under your control this turn, put a +1/+1 counter on it and it gains haste until end of turn.\nLearn. (You may reveal a Lesson card you own from outside the game and put it into your hand, or discard a card to draw a card.)
|
||||||
8
forge-gui/res/cardsfolder/upcoming/gnarled_professor.txt
Normal file
8
forge-gui/res/cardsfolder/upcoming/gnarled_professor.txt
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
Name:Gnarled Professor
|
||||||
|
ManaCost:2 G G
|
||||||
|
Types:Creature Treefolk Druid
|
||||||
|
PT:5/4
|
||||||
|
K:Trample
|
||||||
|
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigLearn | TriggerDescription$ When CARDNAME enters the battlefield, learn. (You may reveal a Lesson card you own from outside the game and put it into your hand, or discard a card to draw a card.)
|
||||||
|
SVar:TrigLearn:DB$ Learn
|
||||||
|
Oracle:Trample\nWhen Gnarled Professor enters the battlefield, learn. (You may reveal a Lesson card you own from outside the game and put it into your hand, or discard a card to draw a card.)
|
||||||
7
forge-gui/res/cardsfolder/upcoming/guiding_voice.txt
Normal file
7
forge-gui/res/cardsfolder/upcoming/guiding_voice.txt
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
Name:Guiding Voice
|
||||||
|
ManaCost:W
|
||||||
|
Types:Sorcery
|
||||||
|
A:SP$ PutCounter | ValidTgts$ Creature | TgtPrompt$ Select target creature | CounterType$ P1P1 | CounterNum$ 1 | SubAbility$ DBLearn | SpellDescription$ Put a +1/+1 counter on target creature.
|
||||||
|
SVar:DBLearn:DB$ Learn | SpellDescription$ Learn. (You may reveal a Lesson card you own from outside the game and put it into your hand, or discard a card to draw a card.)
|
||||||
|
DeckHas:Ability$Counters
|
||||||
|
Oracle:Put a +1/+1 counter on target creature.\nLearn. (You may reveal a Lesson card you own from outside the game and put it into your hand, or discard a card to draw a card.)
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
Name:Hunt for Specimens
|
||||||
|
ManaCost:1 B
|
||||||
|
Types:Sorcery
|
||||||
|
A:SP$ Token | TokenScript$ bg_1_1_pest_lifegain | SubAbility$ DBLearn | SpellDescription$ Create a 1/1 black and green Pest creature token with "When this creature dies, you gain 1 life."
|
||||||
|
SVar:DBLearn:DB$ Learn | SpellDescription$ Learn. (You may reveal a Lesson card you own from outside the game and put it into your hand, or discard a card to draw a card.)
|
||||||
|
DeckHas:Ability$Token & Ability$LifeGain
|
||||||
|
Oracle:Create a 1/1 black and green Pest creature token with "When this creature dies, you gain 1 life."\nLearn. (You may reveal a Lesson card you own from outside the game and put it into your hand, or discard a card to draw a card.)
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
Name:Igneous Inspiration
|
||||||
|
ManaCost:2 R
|
||||||
|
Types:Sorcery
|
||||||
|
A:SP$ DealDamage | ValidTgts$ Creature,Player,Planeswalker | TgtPrompt$ Select any target | NumDmg$ 3 | SubAbility$ DBLearn | SpellDescription$ CARDNAME deals 3 damage to any target.
|
||||||
|
SVar:DBLearn:DB$ Learn | SpellDescription$ Learn. (You may reveal a Lesson card you own from outside the game and put it into your hand, or discard a card to draw a card.)
|
||||||
|
Oracle:Igneous Inspiration deals 3 damage to any target.\nLearn. (You may reveal a Lesson card you own from outside the game and put it into your hand, or discard a card to draw a card.)
|
||||||
9
forge-gui/res/cardsfolder/upcoming/overgrown_arch.txt
Normal file
9
forge-gui/res/cardsfolder/upcoming/overgrown_arch.txt
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
Name:Overgrown Arch
|
||||||
|
ManaCost:1 G
|
||||||
|
Types:Creature Plant Wall
|
||||||
|
PT:0/4
|
||||||
|
K:Defender
|
||||||
|
A:AB$ GainLife | Cost$ T | LifeAmount$ 1 | SpellDescription$ You gain 1 life.
|
||||||
|
A:AB$ Learn | Cost$ 2 Sac<1/CARDNAME> | SpellDescription$ Learn. (You may reveal a Lesson card you own from outside the game and put it into your hand, or discard a card to draw a card.)
|
||||||
|
DeckHas:Ability$LifeGain & Ability$Sacrifice
|
||||||
|
Oracle:Defender\n{T}: You gain 1 life.\n{2}, Sacrifice Overgrown Arch: Learn. (You may reveal a Lesson card you own from outside the game and put it into your hand, or discard a card to draw a card.)
|
||||||
8
forge-gui/res/cardsfolder/upcoming/poets_quill.txt
Normal file
8
forge-gui/res/cardsfolder/upcoming/poets_quill.txt
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
Name:Poet's Quill
|
||||||
|
ManaCost:1 B
|
||||||
|
Types:Artifact — Equipment
|
||||||
|
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigLearn | TriggerDescription$ When CARDNAME enters the battlefield, learn. (You may reveal a Lesson card you own from outside the game and put it into your hand, or discard a card to draw a card.)
|
||||||
|
SVar:TrigLearn:DB$ Learn
|
||||||
|
S:Mode$ Continuous | Affected$ Creature.EquippedBy | AddPower$ 1 | AddToughness$ 1 | AddKeyword$ Lifelink | Description$ Equipped creature gets +1/+1 and has lifelink.
|
||||||
|
K:Equip:1 B
|
||||||
|
Oracle:When Poet's Quill enters the battlefield, learn. (You may reveal a Lesson card you own from outside the game and put it into your hand, or discard a card to draw a card.)\nEquipped creature gets +1/+1 and has lifelink.\nEquip {1}{B}
|
||||||
6
forge-gui/res/cardsfolder/upcoming/pop_quiz.txt
Normal file
6
forge-gui/res/cardsfolder/upcoming/pop_quiz.txt
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
Name:Pop Quiz
|
||||||
|
ManaCost:2 U
|
||||||
|
Types:Instant
|
||||||
|
A:SP$ Draw | Cost$ 2 U | Defined$ You | NumCards$ 1 | SubAbility$ DBLearn | SpellDescription$ Draw a card.
|
||||||
|
SVar:DBLearn:DB$ Learn | SpellDescription$ Learn. (You may reveal a Lesson card you own from outside the game and put it into your hand, or discard a card to draw a card.)
|
||||||
|
Oracle:Draw a card.\nLearn. (You may reveal a Lesson card you own from outside the game and put it into your hand, or discard a card to draw a card.)
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
Name:Professor of Symbology
|
||||||
|
ManaCost:1 W
|
||||||
|
Types:Creature Kor Cleric
|
||||||
|
PT:2/1
|
||||||
|
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigLearn | TriggerDescription$ When CARDNAME enters the battlefield, Learn. (You may reveal a Lesson card you own from outside the game and put it into your hand, or discard a card to draw a card.)
|
||||||
|
SVar:TrigLearn:DB$ Learn
|
||||||
|
Oracle:When Professor of Symbology enters the battlefield, learn. (You may reveal a Lesson card you own from outside the game and put it into your hand, or discard a card to draw a card.)
|
||||||
11
forge-gui/res/cardsfolder/upcoming/retriever_phoenix.txt
Normal file
11
forge-gui/res/cardsfolder/upcoming/retriever_phoenix.txt
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
Name:Retriever Phoenix
|
||||||
|
ManaCost:3 R
|
||||||
|
Types:Creature Phoenix
|
||||||
|
PT:2/2
|
||||||
|
K:Flying
|
||||||
|
K:Haste
|
||||||
|
T:Mode$ ChangesZone | ValidCard$ Card.wasCast+Self | Destination$ Battlefield | Execute$ TrigLearn | TriggerDescription$ When CARDNAME enters the battlefield, if you cast it, learn. (You may reveal a Lesson card you own from outside the game and put it into your hand, or discard a card to draw a card.)
|
||||||
|
R:Event$ Learn | ActiveZones$ Graveyard | ValidPlayer$ You | Optional$ True | ReplaceWith$ Return | IsPresent$ Card.Self | Description$ As long as CARDNAME is in your graveyard, if you would learn, you may instead return CARDNAME to the battlefield.
|
||||||
|
SVar:Return:DB$ ChangeZone | Defined$ Self | Origin$ Graveyard | Destination$ Battlefield
|
||||||
|
DeckHas:Ability$Graveyard
|
||||||
|
Oracle:Flying, haste\nWhen Retriever Phoenix enters the battlefield, if you cast it, learn. (You may reveal a Lesson card you own from outside the game and put it into your hand, or discard a card to draw a card.)\nAs long as Retriever Phoenix is in your graveyard, if you would learn, you may instead return Retriever Phoenix to the battlefield.
|
||||||
7
forge-gui/res/cardsfolder/upcoming/rise_of_extus.txt
Normal file
7
forge-gui/res/cardsfolder/upcoming/rise_of_extus.txt
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
Name:Rise of Extus
|
||||||
|
ManaCost:4 W/B W/B
|
||||||
|
Types:Sorcery
|
||||||
|
A:SP$ ChangeZone | ValidTgts$ Creature | TgtPrompt$ Select target creature | Origin$ Battlefield | Destination$ Exile | SubAbility$ DBExile | SpellDescription$ Exile target creature.
|
||||||
|
SVar:DBExile:DB$ ChangeZone | Origin$ Graveyard | Destination$ Exile | TargetMin$ 0 | ValidTgts$ Instant,Sorcery | TgtPrompt$ Select up to one target instant or sorcery card from a graveyard | SubAbility$ DBLearn | SpellDescription$ Exile up to one target instant or sorcery card from a graveyard.
|
||||||
|
SVar:DBLearn:DB$ Learn | SpellDescription$ Learn. (You may reveal a Lesson card you own from outside the game and put it into your hand, or discard a card to draw a card.)
|
||||||
|
Oracle:Exile target creature. Exile up to one target instant or sorcery card from a graveyard.\nLearn. (You may reveal a Lesson card you own from outside the game and put it into your hand, or discard a card to draw a card.)
|
||||||
10
forge-gui/res/cardsfolder/upcoming/sparring_regimen.txt
Normal file
10
forge-gui/res/cardsfolder/upcoming/sparring_regimen.txt
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
Name:Sparring Regimen
|
||||||
|
ManaCost:2 W
|
||||||
|
Types:Enchantment
|
||||||
|
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigLearn | TriggerDescription$ When CARDNAME enters the battlefield, learn. (You may reveal a Lesson card you own from outside the game and put it into your hand, or discard a card to draw a card.)
|
||||||
|
SVar:TrigLearn:DB$ Learn
|
||||||
|
T:Mode$ AttackersDeclared | AttackingPlayer$ You | Execute$ TrigPutCounter | TriggerZones$ Battlefield | TriggerDescription$ Whenever you attack, put a +1/+1 counter on target attacking creature and untap it.
|
||||||
|
SVar:TrigPutCounter:DB$ PutCounter | CounterType$ P1P1 | CounterNum$ 1 | ValidTgts$ Creature.attacking | TgtPrompt$ Select target attacking creature | SubAbility$ DBUntap
|
||||||
|
SVar:DBUntap:DB$ Untap | Defined$ Targeted
|
||||||
|
DeckHas:Ability$Counters
|
||||||
|
Oracle:When Sparring Regimen enters the battlefield, learn. (You may reveal a Lesson card you own from outside the game and put it into your hand, or discard a card to draw a card.)\nWhenever you attack, put a +1/+1 counter on target attacking creature and untap it.
|
||||||
6
forge-gui/res/cardsfolder/upcoming/study_break.txt
Normal file
6
forge-gui/res/cardsfolder/upcoming/study_break.txt
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
Name:Study Break
|
||||||
|
ManaCost:1 W
|
||||||
|
Types:Instant
|
||||||
|
A:SP$ Tap | Cost$ 1 W | TargetMin$ 0 | TargetMax$ 2 | TgtPrompt$ Choose up to two target creatures | ValidTgts$ Creature | SpellDescription$ Tap up to two target creatures. | SubAbility$ DBLearn
|
||||||
|
SVar:DBLearn:DB$ Learn | SpellDescription$ Learn. (You may reveal a Lesson card you own from outside the game and put it into your hand, or discard a card to draw a card.)
|
||||||
|
Oracle:Tap up to two target creatures.\nLearn. (You may reveal a Lesson card you own from outside the game and put it into your hand, or discard a card to draw a card.)
|
||||||
@@ -476,8 +476,9 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
|||||||
final boolean useUiPointAtCard =
|
final boolean useUiPointAtCard =
|
||||||
(FModel.getPreferences().getPrefBoolean(FPref.UI_SELECT_FROM_CARD_DISPLAYS) && (!GuiBase.getInterface().isLibgdxPort())) ?
|
(FModel.getPreferences().getPrefBoolean(FPref.UI_SELECT_FROM_CARD_DISPLAYS) && (!GuiBase.getInterface().isLibgdxPort())) ?
|
||||||
(cz.is(ZoneType.Battlefield) || cz.is(ZoneType.Hand) || cz.is(ZoneType.Library) ||
|
(cz.is(ZoneType.Battlefield) || cz.is(ZoneType.Hand) || cz.is(ZoneType.Library) ||
|
||||||
cz.is(ZoneType.Graveyard) || cz.is(ZoneType.Exile) || cz.is(ZoneType.Flashback) || cz.is(ZoneType.Command)) :
|
cz.is(ZoneType.Graveyard) || cz.is(ZoneType.Exile) || cz.is(ZoneType.Flashback) ||
|
||||||
(cz.is(ZoneType.Hand) && cz.getPlayer() == player || cz.is(ZoneType.Battlefield));
|
cz.is(ZoneType.Command) || cz.is(ZoneType.Sideboard)) :
|
||||||
|
(cz.is(ZoneType.Hand, player) || cz.is(ZoneType.Battlefield));
|
||||||
if (!useUiPointAtCard) {
|
if (!useUiPointAtCard) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user