mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-18 11:48:02 +00:00
Merge remote-tracking branch 'upstream/master' into collector-number-in-card-list-and-card-db-refactoring
This commit is contained in:
@@ -253,7 +253,10 @@ public class AiController {
|
|||||||
}
|
}
|
||||||
boolean rightapi = false;
|
boolean rightapi = false;
|
||||||
Player activatingPlayer = sa.getActivatingPlayer();
|
Player activatingPlayer = sa.getActivatingPlayer();
|
||||||
|
|
||||||
|
// for xPaid stuff
|
||||||
|
card.setCastSA(sa);
|
||||||
|
|
||||||
// Trigger play improvements
|
// Trigger play improvements
|
||||||
for (final Trigger tr : card.getTriggers()) {
|
for (final Trigger tr : card.getTriggers()) {
|
||||||
// These triggers all care for ETB effects
|
// These triggers all care for ETB effects
|
||||||
@@ -743,7 +746,7 @@ public class AiController {
|
|||||||
return AiPlayDecision.CantPlaySa;
|
return AiPlayDecision.CantPlaySa;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean xCost = sa.getPayCosts().hasXInAnyCostPart();
|
boolean xCost = sa.getPayCosts().hasXInAnyCostPart() || sa.getHostCard().hasStartOfKeyword("Strive");
|
||||||
if (!xCost && !ComputerUtilCost.canPayCost(sa, player)) {
|
if (!xCost && !ComputerUtilCost.canPayCost(sa, player)) {
|
||||||
// for most costs, it's OK to check if they can be paid early in order to avoid running a heavy API check
|
// for most costs, it's OK to check if they can be paid early in order to avoid running a heavy API check
|
||||||
// when the AI won't even be able to play the spell in the first place (even if it could afford it)
|
// when the AI won't even be able to play the spell in the first place (even if it could afford it)
|
||||||
@@ -751,11 +754,11 @@ public class AiController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// state needs to be switched here so API checks evaluate the right face
|
// state needs to be switched here so API checks evaluate the right face
|
||||||
if (sa.getCardState().getStateName() == CardStateName.Modal) {
|
if (sa.getCardState() != null && !sa.getHostCard().isInPlay() && sa.getCardState().getStateName() == CardStateName.Modal) {
|
||||||
sa.getHostCard().setState(CardStateName.Modal, false);
|
sa.getHostCard().setState(CardStateName.Modal, false);
|
||||||
}
|
}
|
||||||
AiPlayDecision canPlay = canPlaySa(sa); // this is the "heaviest" check, which also sets up targets, defines X, etc.
|
AiPlayDecision canPlay = canPlaySa(sa); // this is the "heaviest" check, which also sets up targets, defines X, etc.
|
||||||
if (sa.getCardState().getStateName() == CardStateName.Modal) {
|
if (sa.getCardState() != null && !sa.getHostCard().isInPlay() && sa.getCardState().getStateName() == CardStateName.Modal) {
|
||||||
sa.getHostCard().setState(CardStateName.Original, false);
|
sa.getHostCard().setState(CardStateName.Original, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1754,10 +1757,10 @@ public class AiController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean doTrigger(SpellAbility spell, boolean mandatory) {
|
public boolean doTrigger(SpellAbility spell, boolean mandatory) {
|
||||||
if (spell.getApi() != null)
|
|
||||||
return SpellApiToAi.Converter.get(spell.getApi()).doTriggerAI(player, spell, mandatory);
|
|
||||||
if (spell instanceof WrappedAbility)
|
if (spell instanceof WrappedAbility)
|
||||||
return doTrigger(((WrappedAbility)spell).getWrappedAbility(), mandatory);
|
return doTrigger(((WrappedAbility)spell).getWrappedAbility(), mandatory);
|
||||||
|
if (spell.getApi() != null)
|
||||||
|
return SpellApiToAi.Converter.get(spell.getApi()).doTriggerAI(player, spell, mandatory);
|
||||||
if (spell.getPayCosts() == Cost.Zero && spell.getTargetRestrictions() == null) {
|
if (spell.getPayCosts() == Cost.Zero && spell.getTargetRestrictions() == null) {
|
||||||
// For non-converted triggers (such as Cumulative Upkeep) that don't have costs or targets to worry about
|
// For non-converted triggers (such as Cumulative Upkeep) that don't have costs or targets to worry about
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -695,8 +695,9 @@ public class ComputerUtilCost {
|
|||||||
|
|
||||||
public static int getMaxXValue(SpellAbility sa, Player ai) {
|
public static int getMaxXValue(SpellAbility sa, Player ai) {
|
||||||
final Card source = sa.getHostCard();
|
final Card source = sa.getHostCard();
|
||||||
final SpellAbility root = sa.getRootAbility();
|
SpellAbility root = sa.getRootAbility();
|
||||||
final Cost abCost = root.getPayCosts();
|
final Cost abCost = root.getPayCosts();
|
||||||
|
|
||||||
if (abCost == null || !abCost.hasXInAnyCostPart()) {
|
if (abCost == null || !abCost.hasXInAnyCostPart()) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -827,8 +827,7 @@ public class ComputerUtilMana {
|
|||||||
|
|
||||||
// remove from available lists
|
// remove from available lists
|
||||||
Iterables.removeIf(sourcesForShards.values(), CardTraitPredicates.isHostCard(saPayment.getHostCard()));
|
Iterables.removeIf(sourcesForShards.values(), CardTraitPredicates.isHostCard(saPayment.getHostCard()));
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
final CostPayment pay = new CostPayment(saPayment.getPayCosts(), saPayment);
|
final CostPayment pay = new CostPayment(saPayment.getPayCosts(), saPayment);
|
||||||
if (!pay.payComputerCosts(new AiCostDecision(ai, saPayment))) {
|
if (!pay.payComputerCosts(new AiCostDecision(ai, saPayment))) {
|
||||||
saList.remove(saPayment);
|
saList.remove(saPayment);
|
||||||
@@ -863,8 +862,7 @@ public class ComputerUtilMana {
|
|||||||
if (test) {
|
if (test) {
|
||||||
resetPayment(paymentList);
|
resetPayment(paymentList);
|
||||||
return false;
|
return false;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
System.out.println("ComputerUtil : payManaCost() cost was not paid for " + sa.getHostCard().getName() + ". Didn't find what to pay for " + toPay);
|
System.out.println("ComputerUtil : payManaCost() cost was not paid for " + sa.getHostCard().getName() + ". Didn't find what to pay for " + toPay);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -1233,8 +1231,7 @@ public class ComputerUtilMana {
|
|||||||
if (!(ai.getGame().getPhaseHandler().isPlayerTurn(ai))) {
|
if (!(ai.getGame().getPhaseHandler().isPlayerTurn(ai))) {
|
||||||
AiCardMemory.clearMemorySet(ai, AiCardMemory.MemorySet.HELD_MANA_SOURCES_FOR_ENEMY_DECLBLK);
|
AiCardMemory.clearMemorySet(ai, AiCardMemory.MemorySet.HELD_MANA_SOURCES_FOR_ENEMY_DECLBLK);
|
||||||
AiCardMemory.clearMemorySet(ai, AiCardMemory.MemorySet.CHOSEN_FOG_EFFECT);
|
AiCardMemory.clearMemorySet(ai, AiCardMemory.MemorySet.CHOSEN_FOG_EFFECT);
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
AiCardMemory.clearMemorySet(ai, AiCardMemory.MemorySet.HELD_MANA_SOURCES_FOR_DECLBLK);
|
AiCardMemory.clearMemorySet(ai, AiCardMemory.MemorySet.HELD_MANA_SOURCES_FOR_DECLBLK);
|
||||||
} else {
|
} else {
|
||||||
if ((AiCardMemory.isRememberedCard(ai, sourceCard, AiCardMemory.MemorySet.HELD_MANA_SOURCES_FOR_DECLBLK)) ||
|
if ((AiCardMemory.isRememberedCard(ai, sourceCard, AiCardMemory.MemorySet.HELD_MANA_SOURCES_FOR_DECLBLK)) ||
|
||||||
@@ -1255,8 +1252,7 @@ public class ComputerUtilMana {
|
|||||||
|
|
||||||
if (curPhase == PhaseType.MAIN2 || curPhase == PhaseType.CLEANUP) {
|
if (curPhase == PhaseType.MAIN2 || curPhase == PhaseType.CLEANUP) {
|
||||||
AiCardMemory.clearMemorySet(ai, AiCardMemory.MemorySet.HELD_MANA_SOURCES_FOR_MAIN2);
|
AiCardMemory.clearMemorySet(ai, AiCardMemory.MemorySet.HELD_MANA_SOURCES_FOR_MAIN2);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
if (AiCardMemory.isRememberedCard(ai, sourceCard, AiCardMemory.MemorySet.HELD_MANA_SOURCES_FOR_MAIN2)) {
|
if (AiCardMemory.isRememberedCard(ai, sourceCard, AiCardMemory.MemorySet.HELD_MANA_SOURCES_FOR_MAIN2)) {
|
||||||
// This mana source is held elsewhere for a Main Phase 2 spell.
|
// This mana source is held elsewhere for a Main Phase 2 spell.
|
||||||
return true;
|
return true;
|
||||||
@@ -1266,7 +1262,6 @@ public class ComputerUtilMana {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static ManaCostShard getNextShardToPay(ManaCostBeingPaid cost) {
|
private static ManaCostShard getNextShardToPay(ManaCostBeingPaid cost) {
|
||||||
// mind the priorities
|
// mind the priorities
|
||||||
// * Pay mono-colored first,curPhase == PhaseType.CLEANUP
|
// * Pay mono-colored first,curPhase == PhaseType.CLEANUP
|
||||||
@@ -1352,8 +1347,7 @@ public class ComputerUtilMana {
|
|||||||
String commonColor = ComputerUtilCard.getMostProminentColor(ai.getCardsIn(ZoneType.Hand));
|
String commonColor = ComputerUtilCard.getMostProminentColor(ai.getCardsIn(ZoneType.Hand));
|
||||||
if (!commonColor.isEmpty() && satisfiesColorChoice(abMana, choiceString, MagicColor.toShortString(commonColor)) && abMana.getComboColors().contains(MagicColor.toShortString(commonColor))) {
|
if (!commonColor.isEmpty() && satisfiesColorChoice(abMana, choiceString, MagicColor.toShortString(commonColor)) && abMana.getComboColors().contains(MagicColor.toShortString(commonColor))) {
|
||||||
choice = MagicColor.toShortString(commonColor);
|
choice = MagicColor.toShortString(commonColor);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
// default to first available color
|
// default to first available color
|
||||||
for (String c : comboColors) {
|
for (String c : comboColors) {
|
||||||
if (satisfiesColorChoice(abMana, choiceString, c)) {
|
if (satisfiesColorChoice(abMana, choiceString, c)) {
|
||||||
@@ -1398,8 +1392,7 @@ public class ComputerUtilMana {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
String color = MagicColor.toShortString(manaPart);
|
String color = MagicColor.toShortString(manaPart);
|
||||||
boolean wasNeeded = testCost.ai_payMana(color, p.getManaPool());
|
boolean wasNeeded = testCost.ai_payMana(color, p.getManaPool());
|
||||||
if (!wasNeeded) {
|
if (!wasNeeded) {
|
||||||
|
|||||||
@@ -434,7 +434,7 @@ public abstract class GameState {
|
|||||||
boolean first = true;
|
boolean first = true;
|
||||||
StringBuilder counterString = new StringBuilder();
|
StringBuilder counterString = new StringBuilder();
|
||||||
|
|
||||||
for(Entry<CounterType, Integer> kv : counters.entrySet()) {
|
for (Entry<CounterType, Integer> kv : counters.entrySet()) {
|
||||||
if (!first) {
|
if (!first) {
|
||||||
counterString.append(",");
|
counterString.append(",");
|
||||||
}
|
}
|
||||||
@@ -470,7 +470,7 @@ public abstract class GameState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void parse(List<String> lines) {
|
public void parse(List<String> lines) {
|
||||||
for(String line : lines) {
|
for (String line : lines) {
|
||||||
parseLine(line);
|
parseLine(line);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1110,13 +1110,13 @@ public abstract class GameState {
|
|||||||
|
|
||||||
private void handleCardAttachments() {
|
private void handleCardAttachments() {
|
||||||
// Unattach all permanents first
|
// Unattach all permanents first
|
||||||
for(Entry<Card, Integer> entry : cardToAttachId.entrySet()) {
|
for (Entry<Card, Integer> entry : cardToAttachId.entrySet()) {
|
||||||
Card attachedTo = idToCard.get(entry.getValue());
|
Card attachedTo = idToCard.get(entry.getValue());
|
||||||
attachedTo.unAttachAllCards();
|
attachedTo.unAttachAllCards();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Attach permanents by ID
|
// Attach permanents by ID
|
||||||
for(Entry<Card, Integer> entry : cardToAttachId.entrySet()) {
|
for (Entry<Card, Integer> entry : cardToAttachId.entrySet()) {
|
||||||
Card attachedTo = idToCard.get(entry.getValue());
|
Card attachedTo = idToCard.get(entry.getValue());
|
||||||
Card attacher = entry.getKey();
|
Card attacher = entry.getKey();
|
||||||
if (attacher.isAttachment()) {
|
if (attacher.isAttachment()) {
|
||||||
@@ -1125,7 +1125,7 @@ public abstract class GameState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Enchant players by ID
|
// Enchant players by ID
|
||||||
for(Entry<Card, Integer> entry : cardToEnchantPlayerId.entrySet()) {
|
for (Entry<Card, Integer> entry : cardToEnchantPlayerId.entrySet()) {
|
||||||
// TODO: improve this for game states with more than two players
|
// TODO: improve this for game states with more than two players
|
||||||
Card attacher = entry.getKey();
|
Card attacher = entry.getKey();
|
||||||
Game game = attacher.getGame();
|
Game game = attacher.getGame();
|
||||||
@@ -1136,9 +1136,9 @@ public abstract class GameState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void handleMergedCards() {
|
private void handleMergedCards() {
|
||||||
for(Entry<Card, List<String>> entry : cardToMergedCards.entrySet()) {
|
for (Entry<Card, List<String>> entry : cardToMergedCards.entrySet()) {
|
||||||
Card mergedTo = entry.getKey();
|
Card mergedTo = entry.getKey();
|
||||||
for(String mergedCardName : entry.getValue()) {
|
for (String mergedCardName : entry.getValue()) {
|
||||||
Card c;
|
Card c;
|
||||||
PaperCard pc = StaticData.instance().getCommonCards().getCard(mergedCardName. replace("^", ","));
|
PaperCard pc = StaticData.instance().getCommonCards().getCard(mergedCardName. replace("^", ","));
|
||||||
if (pc == null) {
|
if (pc == null) {
|
||||||
|
|||||||
@@ -1064,7 +1064,7 @@ public class PlayerControllerAi extends PlayerController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean prepareSingleSa(final Card host, final SpellAbility sa, boolean isMandatory){
|
private boolean prepareSingleSa(final Card host, final SpellAbility sa, boolean isMandatory) {
|
||||||
if (sa.hasParam("TargetingPlayer")) {
|
if (sa.hasParam("TargetingPlayer")) {
|
||||||
Player targetingPlayer = AbilityUtils.getDefinedPlayers(host, sa.getParam("TargetingPlayer"), sa).get(0);
|
Player targetingPlayer = AbilityUtils.getDefinedPlayers(host, sa.getParam("TargetingPlayer"), sa).get(0);
|
||||||
sa.setTargetingPlayer(targetingPlayer);
|
sa.setTargetingPlayer(targetingPlayer);
|
||||||
|
|||||||
@@ -115,8 +115,7 @@ public class AttachAi extends SpellAbilityAi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (abCost.getTotalMana().countX() > 0 && sa.getSVar("X").equals("Count$xPaid")) {
|
if (abCost.getTotalMana().countX() > 0 && sa.getSVar("X").equals("Count$xPaid")) {
|
||||||
// Set PayX here to maximum value. (Endless Scream and Venarian
|
// Set PayX here to maximum value. (Endless Scream and Venarian Gold)
|
||||||
// Gold)
|
|
||||||
final int xPay = ComputerUtilCost.getMaxXValue(sa, ai);
|
final int xPay = ComputerUtilCost.getMaxXValue(sa, ai);
|
||||||
|
|
||||||
if (xPay == 0) {
|
if (xPay == 0) {
|
||||||
|
|||||||
@@ -407,6 +407,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
|
|||||||
if (num.contains("X") && sa.getSVar("X").equals("Count$xPaid")) {
|
if (num.contains("X") && sa.getSVar("X").equals("Count$xPaid")) {
|
||||||
// Set PayX here to maximum value.
|
// Set PayX here to maximum value.
|
||||||
int xPay = ComputerUtilCost.getMaxXValue(sa, ai);
|
int xPay = ComputerUtilCost.getMaxXValue(sa, ai);
|
||||||
|
if (xPay == 0) return false;
|
||||||
xPay = Math.min(xPay, list.size());
|
xPay = Math.min(xPay, list.size());
|
||||||
sa.setXManaCostPaid(xPay);
|
sa.setXManaCostPaid(xPay);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ public class CopyPermanentAi extends SpellAbilityAi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ("MomirAvatar".equals(aiLogic)) {
|
if ("MomirAvatar".equals(aiLogic)) {
|
||||||
return SpecialCardAi.MomirVigAvatar.consider(aiPlayer, sa);
|
return SpecialCardAi.MomirVigAvatar.consider(aiPlayer, sa);
|
||||||
} else if ("MimicVat".equals(aiLogic)) {
|
} else if ("MimicVat".equals(aiLogic)) {
|
||||||
return SpecialCardAi.MimicVat.considerCopy(aiPlayer, sa);
|
return SpecialCardAi.MimicVat.considerCopy(aiPlayer, sa);
|
||||||
} else if ("AtEOT".equals(aiLogic)) {
|
} else if ("AtEOT".equals(aiLogic)) {
|
||||||
@@ -59,7 +59,7 @@ public class CopyPermanentAi extends SpellAbilityAi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sa.hasParam("AtEOT") && !aiPlayer.getGame().getPhaseHandler().is(PhaseType.MAIN1)) {
|
if (sa.hasParam("AtEOT") && !ph.is(PhaseType.MAIN1)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,7 +118,6 @@ public class CopyPermanentAi extends SpellAbilityAi {
|
|||||||
final String sourceName = ComputerUtilAbility.getAbilitySourceName(sa);
|
final String sourceName = ComputerUtilAbility.getAbilitySourceName(sa);
|
||||||
final boolean canCopyLegendary = sa.hasParam("NonLegendary");
|
final boolean canCopyLegendary = sa.hasParam("NonLegendary");
|
||||||
|
|
||||||
|
|
||||||
// ////
|
// ////
|
||||||
// Targeting
|
// Targeting
|
||||||
if (sa.usesTargeting()) {
|
if (sa.usesTargeting()) {
|
||||||
|
|||||||
@@ -163,8 +163,6 @@ public class DiscardAi extends SpellAbilityAi {
|
|||||||
return false;
|
return false;
|
||||||
} // discardTargetAI()
|
} // discardTargetAI()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) {
|
protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) {
|
||||||
final TargetRestrictions tgt = sa.getTargetRestrictions();
|
final TargetRestrictions tgt = sa.getTargetRestrictions();
|
||||||
@@ -211,9 +209,8 @@ public class DiscardAi extends SpellAbilityAi {
|
|||||||
return true;
|
return true;
|
||||||
} // discardCheckDrawbackAI()
|
} // discardCheckDrawbackAI()
|
||||||
|
|
||||||
|
|
||||||
public boolean confirmAction(Player player, SpellAbility sa, PlayerActionConfirmMode mode, String message) {
|
public boolean confirmAction(Player player, SpellAbility sa, PlayerActionConfirmMode mode, String message) {
|
||||||
if ( mode == PlayerActionConfirmMode.Random ) { //
|
if ( mode == PlayerActionConfirmMode.Random ) {
|
||||||
// TODO For now AI will always discard Random used currently with: Balduvian Horde and similar cards
|
// TODO For now AI will always discard Random used currently with: Balduvian Horde and similar cards
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,8 +4,10 @@ import java.util.Map;
|
|||||||
|
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
|
|
||||||
|
import forge.ai.ComputerUtil;
|
||||||
import forge.ai.SpellAbilityAi;
|
import forge.ai.SpellAbilityAi;
|
||||||
import forge.game.card.Card;
|
import forge.game.card.Card;
|
||||||
|
import forge.game.card.CardCollection;
|
||||||
import forge.game.card.CounterEnumType;
|
import forge.game.card.CounterEnumType;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
import forge.game.spellability.SpellAbility;
|
import forge.game.spellability.SpellAbility;
|
||||||
@@ -23,15 +25,17 @@ public class LegendaryRuleAi extends SpellAbilityAi {
|
|||||||
protected boolean canPlayAI(Player aiPlayer, SpellAbility sa) {
|
protected boolean canPlayAI(Player aiPlayer, SpellAbility sa) {
|
||||||
return false; // should not get here
|
return false; // should not get here
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Card chooseSingleCard(Player ai, SpellAbility sa, Iterable<Card> options, boolean isOptional, Player targetedPlayer, Map<String, Object> params) {
|
public Card chooseSingleCard(Player ai, SpellAbility sa, Iterable<Card> options, boolean isOptional, Player targetedPlayer, Map<String, Object> params) {
|
||||||
// Choose a single legendary/planeswalker card to keep
|
// Choose a single legendary/planeswalker card to keep
|
||||||
Card firstOption = Iterables.getFirst(options, null);
|
CardCollection legends = new CardCollection(options);
|
||||||
|
CardCollection badOptions = ComputerUtil.choosePermanentsToSacrifice(ai, legends, legends.size() -1, sa, false, false);
|
||||||
|
legends.removeAll(badOptions);
|
||||||
|
Card firstOption = Iterables.getFirst(legends, null);
|
||||||
boolean choosingFromPlanewalkers = firstOption.isPlaneswalker();
|
boolean choosingFromPlanewalkers = firstOption.isPlaneswalker();
|
||||||
|
|
||||||
if ( choosingFromPlanewalkers ) {
|
if (choosingFromPlanewalkers) {
|
||||||
// AI decision making - should AI compare counters?
|
// AI decision making - should AI compare counters?
|
||||||
} else {
|
} else {
|
||||||
// AI decision making - should AI compare damage and debuffs?
|
// AI decision making - should AI compare damage and debuffs?
|
||||||
|
|||||||
@@ -250,9 +250,6 @@ public class TokenAi extends SpellAbilityAi {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) {
|
protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) {
|
||||||
String tokenAmount = sa.getParamOrDefault("TokenAmount", "1");
|
|
||||||
|
|
||||||
final Card source = sa.getHostCard();
|
|
||||||
final TargetRestrictions tgt = sa.getTargetRestrictions();
|
final TargetRestrictions tgt = sa.getTargetRestrictions();
|
||||||
if (tgt != null) {
|
if (tgt != null) {
|
||||||
sa.resetTargets();
|
sa.resetTargets();
|
||||||
@@ -262,16 +259,21 @@ public class TokenAi extends SpellAbilityAi {
|
|||||||
sa.getTargets().add(ai);
|
sa.getTargets().add(ai);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Card actualToken = spawnToken(ai, sa);
|
Card actualToken = spawnToken(ai, sa);
|
||||||
String tokenPower = sa.getParamOrDefault("TokenPower", actualToken.getBasePowerString());
|
String tokenPower = sa.getParamOrDefault("TokenPower", actualToken.getBasePowerString());
|
||||||
String tokenToughness = sa.getParamOrDefault("TokenToughness", actualToken.getBaseToughnessString());
|
String tokenToughness = sa.getParamOrDefault("TokenToughness", actualToken.getBaseToughnessString());
|
||||||
|
String tokenAmount = sa.getParamOrDefault("TokenAmount", "1");
|
||||||
|
final Card source = sa.getHostCard();
|
||||||
|
|
||||||
if ("X".equals(tokenAmount) || "X".equals(tokenPower) || "X".equals(tokenToughness)) {
|
if ("X".equals(tokenAmount) || "X".equals(tokenPower) || "X".equals(tokenToughness)) {
|
||||||
int x = AbilityUtils.calculateAmount(source, tokenAmount, sa);
|
int x = AbilityUtils.calculateAmount(source, tokenAmount, sa);
|
||||||
if (sa.getSVar("X").equals("Count$xPaid")) {
|
if (sa.getSVar("X").equals("Count$xPaid")) {
|
||||||
// Set PayX here to maximum value.
|
if (x == 0) { // already paid outside trigger
|
||||||
x = ComputerUtilCost.getMaxXValue(sa, ai);
|
// Set PayX here to maximum value.
|
||||||
sa.setXManaCostPaid(x);
|
x = ComputerUtilCost.getMaxXValue(sa, ai);
|
||||||
|
sa.setXManaCostPaid(x);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (x <= 0) {
|
if (x <= 0) {
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -414,7 +414,7 @@ public final class CardRules implements ICardCharacteristics {
|
|||||||
String key = colonPos > 0 ? line.substring(0, colonPos) : line;
|
String key = colonPos > 0 ? line.substring(0, colonPos) : line;
|
||||||
String value = colonPos > 0 ? line.substring(1+colonPos).trim() : null;
|
String value = colonPos > 0 ? line.substring(1+colonPos).trim() : null;
|
||||||
|
|
||||||
switch(key.charAt(0)) {
|
switch (key.charAt(0)) {
|
||||||
case 'A':
|
case 'A':
|
||||||
if ("A".equals(key)) {
|
if ("A".equals(key)) {
|
||||||
this.faces[curFace].addAbility(value);
|
this.faces[curFace].addAbility(value);
|
||||||
|
|||||||
@@ -759,7 +759,6 @@ public final class CardType implements Comparable<CardType>, CardTypeView {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///////// Utility methods
|
///////// Utility methods
|
||||||
public static boolean isACardType(final String cardType) {
|
public static boolean isACardType(final String cardType) {
|
||||||
return CoreType.isValidEnum(cardType);
|
return CoreType.isValidEnum(cardType);
|
||||||
|
|||||||
@@ -40,7 +40,6 @@ public class PrintSheet {
|
|||||||
|
|
||||||
private final ItemPool<PaperCard> cardsWithWeights;
|
private final ItemPool<PaperCard> cardsWithWeights;
|
||||||
|
|
||||||
|
|
||||||
private final String name;
|
private final String name;
|
||||||
public PrintSheet(String name0) {
|
public PrintSheet(String name0) {
|
||||||
this(name0, null);
|
this(name0, null);
|
||||||
|
|||||||
@@ -43,9 +43,8 @@ public class DeckGenPool implements IDeckGenPool {
|
|||||||
Iterable<PaperCard> editionCards=Iterables.filter(cards.values(), filter);
|
Iterable<PaperCard> editionCards=Iterables.filter(cards.values(), filter);
|
||||||
if (editionCards.iterator().hasNext()){
|
if (editionCards.iterator().hasNext()){
|
||||||
return editionCards.iterator().next();
|
return editionCards.iterator().next();
|
||||||
}else {
|
|
||||||
return getCard(name);
|
|
||||||
}
|
}
|
||||||
|
return getCard(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -3,9 +3,6 @@ package forge.item;
|
|||||||
import com.google.common.base.Predicate;
|
import com.google.common.base.Predicate;
|
||||||
import com.google.common.base.Predicates;
|
import com.google.common.base.Predicates;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Filtering conditions for miscellaneous InventoryItems.
|
* Filtering conditions for miscellaneous InventoryItems.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -351,4 +351,3 @@ public final class PaperCard implements Comparable<IPaperCard>, InventoryItemFro
|
|||||||
|| (this.getName().equals("Mountain"));
|
|| (this.getName().equals("Mountain"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ public class PaperToken implements InventoryItemFromSet, IPaperCard {
|
|||||||
build.add(subtypes);
|
build.add(subtypes);
|
||||||
|
|
||||||
// Are these keywords sorted?
|
// Are these keywords sorted?
|
||||||
for(String keyword : rules.getMainPart().getKeywords()) {
|
for (String keyword : rules.getMainPart().getKeywords()) {
|
||||||
build.add(keyword);
|
build.add(keyword);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ public class ImageUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static PaperCard getPaperCardFromImageKey(String key) {
|
public static PaperCard getPaperCardFromImageKey(String key) {
|
||||||
if ( key == null ) {
|
if (key == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,6 +42,10 @@ public class ImageUtil {
|
|||||||
String edition = key.substring(index + 1);
|
String edition = key.substring(index + 1);
|
||||||
if (script.startsWith("emblem"))
|
if (script.startsWith("emblem"))
|
||||||
return null;
|
return null;
|
||||||
|
if (null == StaticData.instance().getCardEdition(edition)) {
|
||||||
|
script = key;
|
||||||
|
edition = "???";
|
||||||
|
}
|
||||||
script = script.replaceAll("[0-9]*$", "");
|
script = script.replaceAll("[0-9]*$", "");
|
||||||
return StaticData.instance().getAllTokens().getToken(script, edition);
|
return StaticData.instance().getAllTokens().getToken(script, edition);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -366,7 +366,6 @@ public abstract class CardTraitBase extends GameObject implements IHasCardView,
|
|||||||
if (!Expressions.compare(left, presentCompare, right)) {
|
if (!Expressions.compare(left, presentCompare, right)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (params.containsKey("IsPresent2")) {
|
if (params.containsKey("IsPresent2")) {
|
||||||
|
|||||||
@@ -1633,7 +1633,7 @@ public class GameAction {
|
|||||||
|
|
||||||
recheck = true;
|
recheck = true;
|
||||||
|
|
||||||
Card toKeep = p.getController().chooseSingleEntityForEffect(new CardCollection(cc), new SpellAbility.EmptySa(ApiType.InternalLegendaryRule, null, p),
|
Card toKeep = p.getController().chooseSingleEntityForEffect(new CardCollection(cc), new SpellAbility.EmptySa(ApiType.InternalLegendaryRule, new Card(-1, game), p),
|
||||||
"You have multiple legendary permanents named \""+name+"\" in play.\n\nChoose the one to stay on battlefield (the rest will be moved to graveyard)", null);
|
"You have multiple legendary permanents named \""+name+"\" in play.\n\nChoose the one to stay on battlefield (the rest will be moved to graveyard)", null);
|
||||||
for (Card c: cc) {
|
for (Card c: cc) {
|
||||||
if (c != toKeep) {
|
if (c != toKeep) {
|
||||||
@@ -1905,7 +1905,6 @@ public class GameAction {
|
|||||||
game.getTriggerHandler().runTrigger(TriggerType.NewGame, AbilityKey.newMap(), true);
|
game.getTriggerHandler().runTrigger(TriggerType.NewGame, AbilityKey.newMap(), true);
|
||||||
//</THIS CODE WILL WORK WITH PHASE = NULL>
|
//</THIS CODE WILL WORK WITH PHASE = NULL>
|
||||||
|
|
||||||
|
|
||||||
game.getPhaseHandler().startFirstTurn(first, startGameHook);
|
game.getPhaseHandler().startFirstTurn(first, startGameHook);
|
||||||
//after game ends, ensure Auto-Pass canceled for all players so it doesn't apply to next game
|
//after game ends, ensure Auto-Pass canceled for all players so it doesn't apply to next game
|
||||||
for (Player p : game.getRegisteredPlayers()) {
|
for (Player p : game.getRegisteredPlayers()) {
|
||||||
@@ -1980,7 +1979,6 @@ public class GameAction {
|
|||||||
private void runPreOpeningHandActions(final Player first) {
|
private void runPreOpeningHandActions(final Player first) {
|
||||||
Player takesAction = first;
|
Player takesAction = first;
|
||||||
do {
|
do {
|
||||||
//
|
|
||||||
List<Card> ploys = CardLists.filter(takesAction.getCardsIn(ZoneType.Command), new Predicate<Card>() {
|
List<Card> ploys = CardLists.filter(takesAction.getCardsIn(ZoneType.Command), new Predicate<Card>() {
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Card input) {
|
public boolean apply(Card input) {
|
||||||
@@ -2054,8 +2052,7 @@ public class GameAction {
|
|||||||
public void invoke(final Runnable proc) {
|
public void invoke(final Runnable proc) {
|
||||||
if (ThreadUtil.isGameThread()) {
|
if (ThreadUtil.isGameThread()) {
|
||||||
proc.run();
|
proc.run();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
ThreadUtil.invokeInGameThread(proc);
|
ThreadUtil.invokeInGameThread(proc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -274,8 +274,7 @@ public class GameLogFormatter extends IGameEventVisitor.Base<GameLogEntry> {
|
|||||||
blockers = att.getValue();
|
blockers = att.getValue();
|
||||||
if (blockers.isEmpty()) {
|
if (blockers.isEmpty()) {
|
||||||
sb.append(Localizer.getInstance().getMessage("lblLogPlayerDidntBlockAttacker", controllerName, att.getKey()));
|
sb.append(Localizer.getInstance().getMessage("lblLogPlayerDidntBlockAttacker", controllerName, att.getKey()));
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
sb.append(Localizer.getInstance().getMessage("lblLogPlayerAssignedBlockerToBlockAttacker", controllerName, Lang.joinHomogenous(blockers), att.getKey()));
|
sb.append(Localizer.getInstance().getMessage("lblLogPlayerAssignedBlockerToBlockAttacker", controllerName, Lang.joinHomogenous(blockers), att.getKey()));
|
||||||
}
|
}
|
||||||
firstAttacker = false;
|
firstAttacker = false;
|
||||||
|
|||||||
@@ -178,7 +178,6 @@ public final class AbilityFactory {
|
|||||||
return getAbility(type, type.getApiTypeOf(mapParams), mapParams, parseAbilityCost(state, mapParams, type), state, sVarHolder);
|
return getAbility(type, type.getApiTypeOf(mapParams), mapParams, parseAbilityCost(state, mapParams, type), state, sVarHolder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static Cost parseAbilityCost(final CardState state, Map<String, String> mapParams, AbilityRecordType type) {
|
public static Cost parseAbilityCost(final CardState state, Map<String, String> mapParams, AbilityRecordType type) {
|
||||||
Cost abCost = null;
|
Cost abCost = null;
|
||||||
if (type != AbilityRecordType.SubAbility) {
|
if (type != AbilityRecordType.SubAbility) {
|
||||||
|
|||||||
@@ -1282,7 +1282,8 @@ public class AbilityUtils {
|
|||||||
}
|
}
|
||||||
else if (defined.equals("Opponent")) {
|
else if (defined.equals("Opponent")) {
|
||||||
players.addAll(player.getOpponents());
|
players.addAll(player.getOpponents());
|
||||||
} else if (defined.startsWith("NextPlayerToYour")) {
|
}
|
||||||
|
else if (defined.startsWith("NextPlayerToYour")) {
|
||||||
Direction dir = defined.substring(16).equals("Left") ? Direction.Left : Direction.Right;
|
Direction dir = defined.substring(16).equals("Left") ? Direction.Left : Direction.Right;
|
||||||
players.add(game.getNextPlayerAfter(player, dir));
|
players.add(game.getNextPlayerAfter(player, dir));
|
||||||
}
|
}
|
||||||
@@ -1806,6 +1807,19 @@ public class AbilityUtils {
|
|||||||
}
|
}
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
// Count$TriggeredManaCostDevotion.<Color>
|
||||||
|
if (sq[0].startsWith("TriggeredManaCostDevotion")) {
|
||||||
|
final SpellAbility root = sa.getRootAbility();
|
||||||
|
Card triggeringObject = (Card) root.getTriggeringObject(AbilityKey.Card);
|
||||||
|
int count = 0;
|
||||||
|
byte colorCode = ManaAtom.fromName(sq[1]);
|
||||||
|
for (ManaCostShard sh : triggeringObject.getManaCost()) {
|
||||||
|
if (sh.isColor(colorCode)) {
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
// Count$TriggeredPayingMana.<Color1>.<Color2>
|
// Count$TriggeredPayingMana.<Color1>.<Color2>
|
||||||
if (sq[0].startsWith("TriggeredPayingMana")) {
|
if (sq[0].startsWith("TriggeredPayingMana")) {
|
||||||
final SpellAbility root = sa.getRootAbility();
|
final SpellAbility root = sa.getRootAbility();
|
||||||
@@ -1927,7 +1941,7 @@ public class AbilityUtils {
|
|||||||
// Count$DevotionDual.<color name>.<color name>
|
// Count$DevotionDual.<color name>.<color name>
|
||||||
// Count$Devotion.<color name>
|
// Count$Devotion.<color name>
|
||||||
if (sq[0].contains("Devotion")) {
|
if (sq[0].contains("Devotion")) {
|
||||||
int colorOcurrencices = 0;
|
int colorOccurrences = 0;
|
||||||
String colorName = sq[1];
|
String colorName = sq[1];
|
||||||
if (colorName.contains("Chosen")) {
|
if (colorName.contains("Chosen")) {
|
||||||
colorName = MagicColor.toShortString(c.getChosenColor());
|
colorName = MagicColor.toShortString(c.getChosenColor());
|
||||||
@@ -1939,12 +1953,12 @@ public class AbilityUtils {
|
|||||||
for (Card c0 : player.getCardsIn(ZoneType.Battlefield)) {
|
for (Card c0 : player.getCardsIn(ZoneType.Battlefield)) {
|
||||||
for (ManaCostShard sh : c0.getManaCost()) {
|
for (ManaCostShard sh : c0.getManaCost()) {
|
||||||
if (sh.isColor(colorCode)) {
|
if (sh.isColor(colorCode)) {
|
||||||
colorOcurrencices++;
|
colorOccurrences++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
colorOcurrencices += c0.getAmountOfKeyword("Your devotion to each color and each combination of colors is increased by one.");
|
colorOccurrences += c0.getAmountOfKeyword("Your devotion to each color and each combination of colors is increased by one.");
|
||||||
}
|
}
|
||||||
return doXMath(colorOcurrencices, expr, c, ctb);
|
return doXMath(colorOccurrences, expr, c, ctb);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // end ctb != null
|
} // end ctb != null
|
||||||
|
|||||||
@@ -1,21 +1,15 @@
|
|||||||
package forge.game.ability.effects;
|
package forge.game.ability.effects;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
|
|
||||||
import com.google.common.base.Predicate;
|
import com.google.common.base.Predicate;
|
||||||
import com.google.common.base.Predicates;
|
import com.google.common.base.Predicates;
|
||||||
import com.google.common.collect.Iterables;
|
|
||||||
import com.google.common.collect.Lists;
|
|
||||||
|
|
||||||
import forge.StaticData;
|
import forge.StaticData;
|
||||||
import forge.card.CardFacePredicates;
|
import forge.card.CardFacePredicates;
|
||||||
import forge.card.CardRules;
|
import forge.card.CardRules;
|
||||||
import forge.card.CardRulesPredicates;
|
|
||||||
import forge.card.CardSplitType;
|
import forge.card.CardSplitType;
|
||||||
import forge.card.ICardFace;
|
import forge.card.ICardFace;
|
||||||
import forge.game.ability.AbilityUtils;
|
import forge.game.ability.AbilityUtils;
|
||||||
@@ -26,9 +20,7 @@ import forge.game.card.CardLists;
|
|||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
import forge.game.spellability.SpellAbility;
|
import forge.game.spellability.SpellAbility;
|
||||||
import forge.game.spellability.TargetRestrictions;
|
import forge.game.spellability.TargetRestrictions;
|
||||||
import forge.item.PaperCard;
|
|
||||||
import forge.util.Aggregates;
|
import forge.util.Aggregates;
|
||||||
import forge.util.ComparableOp;
|
|
||||||
import forge.util.Localizer;
|
import forge.util.Localizer;
|
||||||
|
|
||||||
public class ChooseCardNameEffect extends SpellAbilityEffect {
|
public class ChooseCardNameEffect extends SpellAbilityEffect {
|
||||||
|
|||||||
@@ -327,11 +327,10 @@ public class EffectEffect extends SpellAbilityEffect {
|
|||||||
hostCard.addImprintedCard(eff);
|
hostCard.addImprintedCard(eff);
|
||||||
}
|
}
|
||||||
|
|
||||||
eff.updateStateForView();
|
|
||||||
|
|
||||||
// TODO: Add targeting to the effect so it knows who it's dealing with
|
// TODO: Add targeting to the effect so it knows who it's dealing with
|
||||||
game.getTriggerHandler().suppressMode(TriggerType.ChangesZone);
|
game.getTriggerHandler().suppressMode(TriggerType.ChangesZone);
|
||||||
game.getAction().moveTo(ZoneType.Command, eff, sa);
|
game.getAction().moveTo(ZoneType.Command, eff, sa);
|
||||||
|
eff.updateStateForView();
|
||||||
game.getTriggerHandler().clearSuppression(TriggerType.ChangesZone);
|
game.getTriggerHandler().clearSuppression(TriggerType.ChangesZone);
|
||||||
//if (effectTriggers != null) {
|
//if (effectTriggers != null) {
|
||||||
// game.getTriggerHandler().registerActiveTrigger(cmdEffect, false);
|
// game.getTriggerHandler().registerActiveTrigger(cmdEffect, false);
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ public class RegenerateAllEffect extends RegenerateBaseEffect {
|
|||||||
list = CardLists.getValidCards(list, valid.split(","), hostCard.getController(), hostCard, sa);
|
list = CardLists.getValidCards(list, valid.split(","), hostCard.getController(), hostCard, sa);
|
||||||
|
|
||||||
// create Effect for Regeneration
|
// create Effect for Regeneration
|
||||||
createRengenerationEffect(sa, list);
|
createRegenerationEffect(sa, list);
|
||||||
} // regenerateAllResolve
|
} // regenerateAllResolve
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import forge.game.zone.ZoneType;
|
|||||||
|
|
||||||
public abstract class RegenerateBaseEffect extends SpellAbilityEffect {
|
public abstract class RegenerateBaseEffect extends SpellAbilityEffect {
|
||||||
|
|
||||||
public void createRengenerationEffect(SpellAbility sa, final Iterable<Card> list) {
|
public void createRegenerationEffect(SpellAbility sa, final Iterable<Card> list) {
|
||||||
final Card hostCard = sa.getHostCard();
|
final Card hostCard = sa.getHostCard();
|
||||||
final Game game = hostCard.getGame();
|
final Game game = hostCard.getGame();
|
||||||
|
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ public class RegenerateEffect extends RegenerateBaseEffect {
|
|||||||
@Override
|
@Override
|
||||||
public void resolve(SpellAbility sa) {
|
public void resolve(SpellAbility sa) {
|
||||||
// create Effect for Regeneration
|
// create Effect for Regeneration
|
||||||
createRengenerationEffect(sa, getTargetCards(sa));
|
createRegenerationEffect(sa, getTargetCards(sa));
|
||||||
} // regenerateResolve
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ public class RegenerationEffect extends SpellAbilityEffect {
|
|||||||
c.addRegeneratedThisTurn();
|
c.addRegeneratedThisTurn();
|
||||||
|
|
||||||
if (game.getCombat() != null) {
|
if (game.getCombat() != null) {
|
||||||
|
game.getCombat().saveLKI(c);
|
||||||
game.getCombat().removeFromCombat(c);
|
game.getCombat().removeFromCombat(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -59,6 +59,7 @@ public class RemoveFromCombatEffect extends SpellAbilityEffect {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
game.getCombat().saveLKI(c);
|
||||||
combat.removeFromCombat(c);
|
combat.removeFromCombat(c);
|
||||||
|
|
||||||
if (rem) {
|
if (rem) {
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ public class RestartGameEffect extends SpellAbilityEffect {
|
|||||||
game.clearCounterAddedThisTurn();
|
game.clearCounterAddedThisTurn();
|
||||||
game.resetPlayersAttackedOnNextTurn();
|
game.resetPlayersAttackedOnNextTurn();
|
||||||
game.resetPlayersAttackedOnNextTurn();
|
game.resetPlayersAttackedOnNextTurn();
|
||||||
|
game.setMonarch(null);
|
||||||
GameAction action = game.getAction();
|
GameAction action = game.getAction();
|
||||||
|
|
||||||
for (Player p: players) {
|
for (Player p: players) {
|
||||||
@@ -59,6 +60,7 @@ public class RestartGameEffect extends SpellAbilityEffect {
|
|||||||
p.setLandsPlayedLastTurn(0);
|
p.setLandsPlayedLastTurn(0);
|
||||||
p.resetCommanderStats();
|
p.resetCommanderStats();
|
||||||
p.resetCompletedDungeons();
|
p.resetCompletedDungeons();
|
||||||
|
p.setBlessing(false);
|
||||||
|
|
||||||
CardCollection newLibrary = new CardCollection(p.getCardsIn(restartZones, false));
|
CardCollection newLibrary = new CardCollection(p.getCardsIn(restartZones, false));
|
||||||
List<Card> filteredCards = null;
|
List<Card> filteredCards = null;
|
||||||
@@ -111,4 +113,3 @@ public class RestartGameEffect extends SpellAbilityEffect {
|
|||||||
return TextUtil.fastReplace(desc, "CARDNAME", sa.getHostCard().getName());
|
return TextUtil.fastReplace(desc, "CARDNAME", sa.getHostCard().getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ import forge.game.ability.AbilityKey;
|
|||||||
import forge.game.ability.AbilityUtils;
|
import forge.game.ability.AbilityUtils;
|
||||||
import forge.game.ability.ApiType;
|
import forge.game.ability.ApiType;
|
||||||
import forge.game.combat.Combat;
|
import forge.game.combat.Combat;
|
||||||
|
import forge.game.combat.CombatLki;
|
||||||
import forge.game.cost.Cost;
|
import forge.game.cost.Cost;
|
||||||
import forge.game.cost.CostSacrifice;
|
import forge.game.cost.CostSacrifice;
|
||||||
import forge.game.event.*;
|
import forge.game.event.*;
|
||||||
@@ -295,6 +296,8 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
|||||||
private final Table<SpellAbility, StaticAbility, List<String>> chosenModesTurnStatic = HashBasedTable.create();
|
private final Table<SpellAbility, StaticAbility, List<String>> chosenModesTurnStatic = HashBasedTable.create();
|
||||||
private final Table<SpellAbility, StaticAbility, List<String>> chosenModesGameStatic = HashBasedTable.create();
|
private final Table<SpellAbility, StaticAbility, List<String>> chosenModesGameStatic = HashBasedTable.create();
|
||||||
|
|
||||||
|
private CombatLki combatLKI = null;
|
||||||
|
|
||||||
// Enumeration for CMC request types
|
// Enumeration for CMC request types
|
||||||
public enum SplitCMCMode {
|
public enum SplitCMCMode {
|
||||||
CurrentSideCMC,
|
CurrentSideCMC,
|
||||||
@@ -1354,7 +1357,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
|||||||
@Override
|
@Override
|
||||||
public int addCounter(final CounterType counterType, final int n, final Player source, final SpellAbility cause, final boolean applyMultiplier, final boolean fireEvents, GameEntityCounterTable table) {
|
public int addCounter(final CounterType counterType, final int n, final Player source, final SpellAbility cause, final boolean applyMultiplier, final boolean fireEvents, GameEntityCounterTable table) {
|
||||||
int addAmount = n;
|
int addAmount = n;
|
||||||
if(addAmount <= 0 || !canReceiveCounters(counterType)) {
|
if (addAmount <= 0 || !canReceiveCounters(counterType)) {
|
||||||
// As per rule 107.1b
|
// As per rule 107.1b
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -1974,6 +1977,8 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
|||||||
sbx.append(" (").append(inst.getReminderText()).append(")");
|
sbx.append(" (").append(inst.getReminderText()).append(")");
|
||||||
sbLong.append(sbx).append("\r\n");
|
sbLong.append(sbx).append("\r\n");
|
||||||
}
|
}
|
||||||
|
} else if (keyword.startsWith("Trample:")) {
|
||||||
|
sbLong.append("Trample over planeswalkers").append(" (").append(inst.getReminderText()).append(")").append("\r\n");
|
||||||
} else if (keyword.startsWith("Hexproof:")) {
|
} else if (keyword.startsWith("Hexproof:")) {
|
||||||
final String[] k = keyword.split(":");
|
final String[] k = keyword.split(":");
|
||||||
sbLong.append("Hexproof from ").append(k[2])
|
sbLong.append("Hexproof from ").append(k[2])
|
||||||
@@ -2000,7 +2005,6 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
|||||||
|| keyword.equals("Suspend") // for the ones without amount
|
|| keyword.equals("Suspend") // for the ones without amount
|
||||||
|| keyword.equals("Foretell") // for the ones without cost
|
|| keyword.equals("Foretell") // for the ones without cost
|
||||||
|| keyword.equals("Hideaway") || keyword.equals("Ascend")
|
|| keyword.equals("Hideaway") || keyword.equals("Ascend")
|
||||||
|| keyword.equals("Trample over planeswalkers")
|
|
||||||
|| keyword.equals("Totem armor") || keyword.equals("Battle cry")
|
|| keyword.equals("Totem armor") || keyword.equals("Battle cry")
|
||||||
|| keyword.equals("Devoid") || keyword.equals("Riot")){
|
|| keyword.equals("Devoid") || keyword.equals("Riot")){
|
||||||
sbLong.append(keyword).append(" (").append(inst.getReminderText()).append(")");
|
sbLong.append(keyword).append(" (").append(inst.getReminderText()).append(")");
|
||||||
@@ -4670,6 +4674,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
|||||||
setPhasedOut(!phasedOut);
|
setPhasedOut(!phasedOut);
|
||||||
final Combat combat = getGame().getPhaseHandler().getCombat();
|
final Combat combat = getGame().getPhaseHandler().getCombat();
|
||||||
if (combat != null && phasedOut) {
|
if (combat != null && phasedOut) {
|
||||||
|
combat.saveLKI(this);
|
||||||
combat.removeFromCombat(this);
|
combat.removeFromCombat(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6167,7 +6172,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (source == null){
|
if (source == null) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6924,4 +6929,18 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
|||||||
public final void clearUntilLeavesBattlefield() {
|
public final void clearUntilLeavesBattlefield() {
|
||||||
untilLeavesBattlefield = view.clearCards(untilLeavesBattlefield, TrackableProperty.UntilLeavesBattlefield);
|
untilLeavesBattlefield = view.clearCards(untilLeavesBattlefield, TrackableProperty.UntilLeavesBattlefield);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public CombatLki getCombatLKI() {
|
||||||
|
return combatLKI;
|
||||||
|
}
|
||||||
|
public void setCombatLKI(CombatLki combatLKI) {
|
||||||
|
this.combatLKI = combatLKI;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isAttacking() {
|
||||||
|
if (getCombatLKI() != null) {
|
||||||
|
return getCombatLKI().isAttacker;
|
||||||
|
}
|
||||||
|
return getGame().getCombat().isAttacking(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -518,6 +518,7 @@ public class CardFactoryUtil {
|
|||||||
final Set<String> protectionkw = Sets.newHashSet();
|
final Set<String> protectionkw = Sets.newHashSet();
|
||||||
final Set<String> protectionColorkw = Sets.newHashSet();
|
final Set<String> protectionColorkw = Sets.newHashSet();
|
||||||
final Set<String> hexproofkw = Sets.newHashSet();
|
final Set<String> hexproofkw = Sets.newHashSet();
|
||||||
|
final Set<String> tramplekw = Sets.newHashSet();
|
||||||
final Set<String> allkw = Sets.newHashSet();
|
final Set<String> allkw = Sets.newHashSet();
|
||||||
|
|
||||||
for (Card c : CardLists.getValidCards(cardlist, restrictions, p, host, null)) {
|
for (Card c : CardLists.getValidCards(cardlist, restrictions, p, host, null)) {
|
||||||
@@ -535,6 +536,8 @@ public class CardFactoryUtil {
|
|||||||
}
|
}
|
||||||
} else if (k.startsWith("Hexproof")) {
|
} else if (k.startsWith("Hexproof")) {
|
||||||
hexproofkw.add(k);
|
hexproofkw.add(k);
|
||||||
|
} else if (k.startsWith("Trample")) {
|
||||||
|
tramplekw.add(k);
|
||||||
}
|
}
|
||||||
allkw.add(k);
|
allkw.add(k);
|
||||||
}
|
}
|
||||||
@@ -548,6 +551,8 @@ public class CardFactoryUtil {
|
|||||||
filteredkw.addAll(landkw);
|
filteredkw.addAll(landkw);
|
||||||
} else if (keyword.equals("Hexproof")) {
|
} else if (keyword.equals("Hexproof")) {
|
||||||
filteredkw.addAll(hexproofkw);
|
filteredkw.addAll(hexproofkw);
|
||||||
|
} else if (keyword.equals("Trample")) {
|
||||||
|
filteredkw.addAll(tramplekw);
|
||||||
} else if (allkw.contains(keyword)) {
|
} else if (allkw.contains(keyword)) {
|
||||||
filteredkw.add(keyword);
|
filteredkw.add(keyword);
|
||||||
}
|
}
|
||||||
@@ -781,7 +786,7 @@ public class CardFactoryUtil {
|
|||||||
+ "TriggerZones$ Battlefield | Secondary$ True | TriggerDescription$ "
|
+ "TriggerZones$ Battlefield | Secondary$ True | TriggerDescription$ "
|
||||||
+ "Annihilator " + n + " (" + inst.getReminderText() + ")";
|
+ "Annihilator " + n + " (" + inst.getReminderText() + ")";
|
||||||
|
|
||||||
final String effect = "DB$ Sacrifice | Defined$ DefendingPlayer | SacValid$ Permanent | Amount$ " + k[1];
|
final String effect = "DB$ Sacrifice | Defined$ TriggeredDefendingPlayer | SacValid$ Permanent | Amount$ " + k[1];
|
||||||
|
|
||||||
final Trigger trigger = TriggerHandler.parseTrigger(trig, card, intrinsic);
|
final Trigger trigger = TriggerHandler.parseTrigger(trig, card, intrinsic);
|
||||||
trigger.setOverridingAbility(AbilityFactory.getAbility(effect, card));
|
trigger.setOverridingAbility(AbilityFactory.getAbility(effect, card));
|
||||||
@@ -1516,7 +1521,7 @@ public class CardFactoryUtil {
|
|||||||
} else if (keyword.equals("Provoke")) {
|
} else if (keyword.equals("Provoke")) {
|
||||||
final String actualTrigger = "Mode$ Attacks | ValidCard$ Card.Self | OptionalDecider$ You | Secondary$ True"
|
final String actualTrigger = "Mode$ Attacks | ValidCard$ Card.Self | OptionalDecider$ You | Secondary$ True"
|
||||||
+ " | TriggerDescription$ Provoke (" + inst.getReminderText() + ")";
|
+ " | TriggerDescription$ Provoke (" + inst.getReminderText() + ")";
|
||||||
final String blockStr = "DB$ MustBlock | ValidTgts$ Creature.DefenderCtrl | TgtPrompt$ Select target creature defending player controls";
|
final String blockStr = "DB$ MustBlock | ValidTgts$ Creature.ControlledBy TriggeredDefendingPlayer | TgtPrompt$ Select target creature defending player controls";
|
||||||
final String untapStr = "DB$ Untap | Defined$ Targeted";
|
final String untapStr = "DB$ Untap | Defined$ Targeted";
|
||||||
|
|
||||||
SpellAbility blockSA = AbilityFactory.getAbility(blockStr, card);
|
SpellAbility blockSA = AbilityFactory.getAbility(blockStr, card);
|
||||||
|
|||||||
@@ -1412,8 +1412,7 @@ public class CardProperty {
|
|||||||
// These predicated refer to ongoing combat. If no combat happens, they'll return false (meaning not attacking/blocking ATM)
|
// These predicated refer to ongoing combat. If no combat happens, they'll return false (meaning not attacking/blocking ATM)
|
||||||
else if (property.startsWith("attacking")) {
|
else if (property.startsWith("attacking")) {
|
||||||
if (null == combat) return false;
|
if (null == combat) return false;
|
||||||
if (property.equals("attacking")) return combat.isAttacking(card);
|
if (property.equals("attacking")) return card.isAttacking();
|
||||||
if (property.equals("attackingLKI")) return combat.isLKIAttacking(card);
|
|
||||||
if (property.equals("attackingYou")) return combat.isAttacking(card, sourceController);
|
if (property.equals("attackingYou")) return combat.isAttacking(card, sourceController);
|
||||||
if (property.equals("attackingSame")) {
|
if (property.equals("attackingSame")) {
|
||||||
final GameEntity attacked = combat.getDefenderByAttacker(source);
|
final GameEntity attacked = combat.getDefenderByAttacker(source);
|
||||||
@@ -1514,12 +1513,10 @@ public class CardProperty {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
String valid = property.split(" ")[1];
|
String valid = property.split(" ")[1];
|
||||||
for(Card c : blocked) {
|
if (Iterables.any(blocked, CardPredicates.restriction(valid, card.getController(), source, spellAbility))) {
|
||||||
if (c.isValid(valid, card.getController(), source, spellAbility)) {
|
return true;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
for(Card c : AbilityUtils.getDefinedCards(source, valid, spellAbility)) {
|
for (Card c : AbilityUtils.getDefinedCards(source, valid, spellAbility)) {
|
||||||
if (blocked.contains(c)) {
|
if (blocked.contains(c)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -323,6 +323,10 @@ public final class CardUtil {
|
|||||||
|
|
||||||
newCopy.setExiledWith(getLKICopy(in.getExiledWith(), cachedMap));
|
newCopy.setExiledWith(getLKICopy(in.getExiledWith(), cachedMap));
|
||||||
|
|
||||||
|
if (in.getGame().getCombat() != null) {
|
||||||
|
newCopy.setCombatLKI(in.getGame().getCombat().saveLKI(newCopy));
|
||||||
|
}
|
||||||
|
|
||||||
return newCopy;
|
return newCopy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -97,6 +97,9 @@ public class CounterType implements Comparable<CounterType>, Serializable {
|
|||||||
final String[] k = sVal.split(":");
|
final String[] k = sVal.split(":");
|
||||||
return "Hexproof from " + k[2];
|
return "Hexproof from " + k[2];
|
||||||
}
|
}
|
||||||
|
if (sVal.startsWith("Trample:")) {
|
||||||
|
return "Trample over Planeswalkers";
|
||||||
|
}
|
||||||
return sVal;
|
return sVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,6 +122,9 @@ public class CounterType implements Comparable<CounterType>, Serializable {
|
|||||||
if (sVal.startsWith("Hexproof:")) {
|
if (sVal.startsWith("Hexproof:")) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if (sVal.startsWith("Trample:")) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
return keywordCounter.contains(sVal);
|
return keywordCounter.contains(sVal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ import forge.game.card.Card;
|
|||||||
import forge.game.card.CardCollection;
|
import forge.game.card.CardCollection;
|
||||||
import forge.game.card.CardCollectionView;
|
import forge.game.card.CardCollectionView;
|
||||||
import forge.game.card.CardDamageMap;
|
import forge.game.card.CardDamageMap;
|
||||||
|
import forge.game.card.CardUtil;
|
||||||
import forge.game.keyword.Keyword;
|
import forge.game.keyword.Keyword;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
import forge.game.replacement.ReplacementType;
|
import forge.game.replacement.ReplacementType;
|
||||||
@@ -75,7 +76,7 @@ public class Combat {
|
|||||||
|
|
||||||
private Map<Card, CardCollection> attackersOrderedForDamageAssignment = Maps.newHashMap();
|
private Map<Card, CardCollection> attackersOrderedForDamageAssignment = Maps.newHashMap();
|
||||||
private Map<Card, CardCollection> blockersOrderedForDamageAssignment = Maps.newHashMap();
|
private Map<Card, CardCollection> blockersOrderedForDamageAssignment = Maps.newHashMap();
|
||||||
private Map<GameEntity, CombatLki> lkiCache = Maps.newHashMap();
|
private CardCollection lkiCache = new CardCollection();
|
||||||
private CardDamageMap damageMap = new CardDamageMap();
|
private CardDamageMap damageMap = new CardDamageMap();
|
||||||
|
|
||||||
// List holds creatures who have dealt 1st strike damage to disallow them deal damage on regular basis (unless they have double-strike KW)
|
// List holds creatures who have dealt 1st strike damage to disallow them deal damage on regular basis (unless they have double-strike KW)
|
||||||
@@ -300,7 +301,7 @@ public class Combat {
|
|||||||
return ab;
|
return ab;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CombatLki lki = lkiCache.get(c);
|
CombatLki lki = lkiCache.get(c).getCombatLKI();
|
||||||
return lki == null || !lki.isAttacker ? null : lki.getFirstBand();
|
return lki == null || !lki.isAttacker ? null : lki.getFirstBand();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -316,14 +317,6 @@ public class Combat {
|
|||||||
return Lists.newArrayList(attackedByBands.values());
|
return Lists.newArrayList(attackedByBands.values());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if a card is attacking, returns true if the card was attacking when it left the battlefield
|
|
||||||
*/
|
|
||||||
public final boolean isLKIAttacking(final Card c) {
|
|
||||||
AttackingBand ab = getBandOfAttacker(c);
|
|
||||||
return ab != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isAttacking(Card card, GameEntity defender) {
|
public boolean isAttacking(Card card, GameEntity defender) {
|
||||||
AttackingBand ab = getBandOfAttacker(card);
|
AttackingBand ab = getBandOfAttacker(card);
|
||||||
for (Entry<GameEntity, AttackingBand> ee : attackedByBands.entries()) {
|
for (Entry<GameEntity, AttackingBand> ee : attackedByBands.entries()) {
|
||||||
@@ -786,7 +779,7 @@ public class Combat {
|
|||||||
assignedDamage = true;
|
assignedDamage = true;
|
||||||
GameEntity defender = getDefenderByAttacker(band);
|
GameEntity defender = getDefenderByAttacker(band);
|
||||||
// If the Attacker is unblocked, or it's a trampler and has 0 blockers, deal damage to defender
|
// If the Attacker is unblocked, or it's a trampler and has 0 blockers, deal damage to defender
|
||||||
if (defender instanceof Card && attacker.hasKeyword("Trample over planeswalkers")) {
|
if (defender instanceof Card && attacker.hasKeyword("Trample:Planeswalker")) {
|
||||||
if (orderedBlockers == null || orderedBlockers.isEmpty()) {
|
if (orderedBlockers == null || orderedBlockers.isEmpty()) {
|
||||||
CardCollection cc = new CardCollection();
|
CardCollection cc = new CardCollection();
|
||||||
cc.add((Card)defender);
|
cc.add((Card)defender);
|
||||||
@@ -918,7 +911,7 @@ public class Combat {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
CombatLki lki = lkiCache.get(blocker);
|
CombatLki lki = lkiCache.get(blocker).getCombatLKI();
|
||||||
return null != lki && !lki.isAttacker; // was blocking something anyway
|
return null != lki && !lki.isAttacker; // was blocking something anyway
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -933,21 +926,36 @@ public class Combat {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
CombatLki lki = lkiCache.get(blocker);
|
CombatLki lki = lkiCache.get(blocker).getCombatLKI();
|
||||||
return null != lki && !lki.isAttacker && lki.relatedBands.contains(ab); // was blocking that very band
|
return null != lki && !lki.isAttacker && lki.relatedBands.contains(ab); // was blocking that very band
|
||||||
}
|
}
|
||||||
|
|
||||||
public void saveLKI(Card lastKnownInfo) {
|
public CombatLki saveLKI(Card lki) {
|
||||||
|
if (!lki.isLKI()) {
|
||||||
|
lki = CardUtil.getLKICopy(lki);
|
||||||
|
}
|
||||||
FCollectionView<AttackingBand> attackersBlocked = null;
|
FCollectionView<AttackingBand> attackersBlocked = null;
|
||||||
final AttackingBand attackingBand = getBandOfAttacker(lastKnownInfo);
|
final AttackingBand attackingBand = getBandOfAttacker(lki);
|
||||||
final boolean isAttacker = attackingBand != null;
|
final boolean isAttacker = attackingBand != null;
|
||||||
if (!isAttacker) {
|
if (isAttacker) {
|
||||||
attackersBlocked = getAttackingBandsBlockedBy(lastKnownInfo);
|
boolean found = false;
|
||||||
|
for (AttackingBand ab : attackedByBands.values()) {
|
||||||
|
if (ab.contains(lki)) {
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
attackersBlocked = getAttackingBandsBlockedBy(lki);
|
||||||
if (attackersBlocked.isEmpty()) {
|
if (attackersBlocked.isEmpty()) {
|
||||||
return; // card was not even in combat
|
return null; // card was not even in combat
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
lkiCache.add(lki);
|
||||||
final FCollectionView<AttackingBand> relatedBands = isAttacker ? new FCollection<>(attackingBand) : attackersBlocked;
|
final FCollectionView<AttackingBand> relatedBands = isAttacker ? new FCollection<>(attackingBand) : attackersBlocked;
|
||||||
lkiCache.put(lastKnownInfo, new CombatLki(isAttacker, relatedBands));
|
return new CombatLki(isAttacker, relatedBands);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -240,8 +240,7 @@ public class Cost implements Serializable {
|
|||||||
xCantBe0 = true;
|
xCantBe0 = true;
|
||||||
} else if ("Mandatory".equals(part)) {
|
} else if ("Mandatory".equals(part)) {
|
||||||
this.isMandatory = true;
|
this.isMandatory = true;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
CostPart cp = parseCostPart(part, tapCost, untapCost);
|
CostPart cp = parseCostPart(part, tapCost, untapCost);
|
||||||
if (null != cp )
|
if (null != cp )
|
||||||
if (cp instanceof CostPartMana ) {
|
if (cp instanceof CostPartMana ) {
|
||||||
@@ -268,7 +267,6 @@ public class Cost implements Serializable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static CostPart parseCostPart(String parse, boolean tapCost, boolean untapCost) {
|
private static CostPart parseCostPart(String parse, boolean tapCost, boolean untapCost) {
|
||||||
|
|
||||||
if (parse.startsWith("Mana<")) {
|
if (parse.startsWith("Mana<")) {
|
||||||
final String[] splitStr = TextUtil.split(abCostParse(parse, 1)[0], '\\');
|
final String[] splitStr = TextUtil.split(abCostParse(parse, 1)[0], '\\');
|
||||||
final String restriction = splitStr.length > 1 ? splitStr[1] : null;
|
final String restriction = splitStr.length > 1 ? splitStr[1] : null;
|
||||||
|
|||||||
@@ -10,8 +10,7 @@ public class GameEventAnteCardsSelected extends GameEvent {
|
|||||||
public GameEventAnteCardsSelected(Multimap<Player, Card> list) {
|
public GameEventAnteCardsSelected(Multimap<Player, Card> list) {
|
||||||
cards = list;
|
cards = list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> T visit(IGameEventVisitor<T> visitor) {
|
public <T> T visit(IGameEventVisitor<T> visitor) {
|
||||||
return visitor.visit(this);
|
return visitor.visit(this);
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ public class GameEventAttackersDeclared extends GameEvent {
|
|||||||
|
|
||||||
public final Player player;
|
public final Player player;
|
||||||
public final Multimap<GameEntity, Card> attackersMap;
|
public final Multimap<GameEntity, Card> attackersMap;
|
||||||
|
|
||||||
public GameEventAttackersDeclared(Player playerTurn, Multimap<GameEntity, Card> attackersMap) {
|
public GameEventAttackersDeclared(Player playerTurn, Multimap<GameEntity, Card> attackersMap) {
|
||||||
this.player = playerTurn;
|
this.player = playerTurn;
|
||||||
this.attackersMap = attackersMap;
|
this.attackersMap = attackersMap;
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ public class GameEventBlockersDeclared extends GameEvent {
|
|||||||
|
|
||||||
public final Map<GameEntity, MapOfLists<Card, Card>> blockers;
|
public final Map<GameEntity, MapOfLists<Card, Card>> blockers;
|
||||||
public final Player defendingPlayer;
|
public final Player defendingPlayer;
|
||||||
|
|
||||||
public GameEventBlockersDeclared(Player who, Map<GameEntity, MapOfLists<Card, Card>> blockers) {
|
public GameEventBlockersDeclared(Player who, Map<GameEntity, MapOfLists<Card, Card>> blockers) {
|
||||||
this.blockers = blockers;
|
this.blockers = blockers;
|
||||||
defendingPlayer = who;
|
defendingPlayer = who;
|
||||||
|
|||||||
@@ -8,13 +8,13 @@ public class GameEventCardAttachment extends GameEvent {
|
|||||||
public final Card equipment;
|
public final Card equipment;
|
||||||
public final GameEntity newTarget; // can enchant player, I'm ssaving a class to enchants - it could be incorrect.
|
public final GameEntity newTarget; // can enchant player, I'm ssaving a class to enchants - it could be incorrect.
|
||||||
public final GameEntity oldEntiy;
|
public final GameEntity oldEntiy;
|
||||||
|
|
||||||
public GameEventCardAttachment(Card attachment, GameEntity formerEntity, GameEntity newEntity) {
|
public GameEventCardAttachment(Card attachment, GameEntity formerEntity, GameEntity newEntity) {
|
||||||
this.equipment = attachment;
|
this.equipment = attachment;
|
||||||
this.newTarget = newEntity;
|
this.newTarget = newEntity;
|
||||||
this.oldEntiy = formerEntity;
|
this.oldEntiy = formerEntity;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> T visit(IGameEventVisitor<T> visitor) {
|
public <T> T visit(IGameEventVisitor<T> visitor) {
|
||||||
return visitor.visit(this);
|
return visitor.visit(this);
|
||||||
|
|||||||
@@ -6,11 +6,10 @@ import forge.util.TextUtil;
|
|||||||
|
|
||||||
public class GameEventCardChangeZone extends GameEvent {
|
public class GameEventCardChangeZone extends GameEvent {
|
||||||
|
|
||||||
|
public final Card card;
|
||||||
|
public final Zone from;
|
||||||
|
public final Zone to;
|
||||||
|
|
||||||
public final Card card;
|
|
||||||
public final Zone from;
|
|
||||||
public final Zone to;
|
|
||||||
|
|
||||||
public GameEventCardChangeZone(Card c, Zone zoneFrom, Zone zoneTo) {
|
public GameEventCardChangeZone(Card c, Zone zoneFrom, Zone zoneTo) {
|
||||||
card = c;
|
card = c;
|
||||||
from = zoneFrom;
|
from = zoneFrom;
|
||||||
@@ -21,7 +20,7 @@ public class GameEventCardChangeZone extends GameEvent {
|
|||||||
public <T> T visit(IGameEventVisitor<T> visitor) {
|
public <T> T visit(IGameEventVisitor<T> visitor) {
|
||||||
return visitor.visit(this);
|
return visitor.visit(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see java.lang.Object#toString()
|
* @see java.lang.Object#toString()
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ public class GameEventCardCounters extends GameEvent {
|
|||||||
this.oldValue = old;
|
this.oldValue = old;
|
||||||
this.newValue = newValue;
|
this.newValue = newValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> T visit(IGameEventVisitor<T> visitor) {
|
public <T> T visit(IGameEventVisitor<T> visitor) {
|
||||||
return visitor.visit(this);
|
return visitor.visit(this);
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package forge.game.event;
|
|||||||
import forge.game.card.Card;
|
import forge.game.card.Card;
|
||||||
|
|
||||||
public class GameEventCardDamaged extends GameEvent {
|
public class GameEventCardDamaged extends GameEvent {
|
||||||
|
|
||||||
public enum DamageType {
|
public enum DamageType {
|
||||||
Normal,
|
Normal,
|
||||||
M1M1Counters,
|
M1M1Counters,
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package forge.game.event;
|
package forge.game.event;
|
||||||
|
|
||||||
public class GameEventCardDestroyed extends GameEvent {
|
public class GameEventCardDestroyed extends GameEvent {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> T visit(IGameEventVisitor<T> visitor) {
|
public <T> T visit(IGameEventVisitor<T> visitor) {
|
||||||
return visitor.visit(this);
|
return visitor.visit(this);
|
||||||
|
|||||||
@@ -3,12 +3,12 @@ package forge.game.event;
|
|||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
|
|
||||||
public class GameEventCardModeChosen extends GameEvent {
|
public class GameEventCardModeChosen extends GameEvent {
|
||||||
|
|
||||||
public final Player player;
|
public final Player player;
|
||||||
public final String cardName;
|
public final String cardName;
|
||||||
public final String mode;
|
public final String mode;
|
||||||
public final boolean log;
|
public final boolean log;
|
||||||
|
|
||||||
public GameEventCardModeChosen(Player player, String cardName, String mode, boolean log) {
|
public GameEventCardModeChosen(Player player, String cardName, String mode, boolean log) {
|
||||||
this.player = player;
|
this.player = player;
|
||||||
this.cardName = cardName;
|
this.cardName = cardName;
|
||||||
@@ -21,5 +21,3 @@ public class GameEventCardModeChosen extends GameEvent {
|
|||||||
return visitor.visit(this);
|
return visitor.visit(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ public class GameEventCardPhased extends GameEvent {
|
|||||||
|
|
||||||
public final Card card;
|
public final Card card;
|
||||||
public final boolean phaseState;
|
public final boolean phaseState;
|
||||||
|
|
||||||
public GameEventCardPhased(Card card, boolean state) {
|
public GameEventCardPhased(Card card, boolean state) {
|
||||||
this.card = card;
|
this.card = card;
|
||||||
phaseState = state;
|
phaseState = state;
|
||||||
@@ -20,7 +20,7 @@ public class GameEventCardPhased extends GameEvent {
|
|||||||
public <T> T visit(IGameEventVisitor<T> visitor) {
|
public <T> T visit(IGameEventVisitor<T> visitor) {
|
||||||
return visitor.visit(this);
|
return visitor.visit(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see java.lang.Object#toString()
|
* @see java.lang.Object#toString()
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package forge.game.event;
|
package forge.game.event;
|
||||||
|
|
||||||
public class GameEventCardRegenerated extends GameEvent {
|
public class GameEventCardRegenerated extends GameEvent {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> T visit(IGameEventVisitor<T> visitor) {
|
public <T> T visit(IGameEventVisitor<T> visitor) {
|
||||||
return visitor.visit(this);
|
return visitor.visit(this);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package forge.game.event;
|
package forge.game.event;
|
||||||
|
|
||||||
public class GameEventCardSacrificed extends GameEvent {
|
public class GameEventCardSacrificed extends GameEvent {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> T visit(IGameEventVisitor<T> visitor) {
|
public <T> T visit(IGameEventVisitor<T> visitor) {
|
||||||
return visitor.visit(this);
|
return visitor.visit(this);
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ public class GameEventCardStatsChanged extends GameEvent {
|
|||||||
public GameEventCardStatsChanged(Card affected) {
|
public GameEventCardStatsChanged(Card affected) {
|
||||||
cards = Arrays.asList(affected);
|
cards = Arrays.asList(affected);
|
||||||
}
|
}
|
||||||
|
|
||||||
public GameEventCardStatsChanged(Collection<Card> affected) {
|
public GameEventCardStatsChanged(Collection<Card> affected) {
|
||||||
cards = affected;
|
cards = affected;
|
||||||
}
|
}
|
||||||
@@ -31,13 +31,13 @@ public class GameEventCardStatsChanged extends GameEvent {
|
|||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
return visitor.visit(this);
|
return visitor.visit(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
Card card = Iterables.getFirst(cards, null);
|
Card card = Iterables.getFirst(cards, null);
|
||||||
if ( null == card )
|
if (null == card)
|
||||||
return "Card state changes: (empty list)";
|
return "Card state changes: (empty list)";
|
||||||
if( cards.size() == 1)
|
if (cards.size() == 1)
|
||||||
return "Card state changes: " + card.getName() +
|
return "Card state changes: " + card.getName() +
|
||||||
" (" + StringUtils.join(card.getType(), ' ') + ") " +
|
" (" + StringUtils.join(card.getType(), ' ') + ") " +
|
||||||
card.getNetPower() + "/" + card.getNetToughness();
|
card.getNetPower() + "/" + card.getNetToughness();
|
||||||
|
|||||||
@@ -10,8 +10,7 @@ public class GameEventCardTapped extends GameEvent {
|
|||||||
this.tapped = tapped;
|
this.tapped = tapped;
|
||||||
this.card = card;
|
this.card = card;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> T visit(IGameEventVisitor<T> visitor) {
|
public <T> T visit(IGameEventVisitor<T> visitor) {
|
||||||
return visitor.visit(this);
|
return visitor.visit(this);
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ public class GameEventCombatEnded extends GameEvent {
|
|||||||
|
|
||||||
public final List<Card> attackers;
|
public final List<Card> attackers;
|
||||||
public final List<Card> blockers;
|
public final List<Card> blockers;
|
||||||
|
|
||||||
public GameEventCombatEnded(List<Card> attackers, List<Card> blockers) {
|
public GameEventCombatEnded(List<Card> attackers, List<Card> blockers) {
|
||||||
this.attackers = attackers;
|
this.attackers = attackers;
|
||||||
this.blockers = blockers;
|
this.blockers = blockers;
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
package forge.game.event;
|
package forge.game.event;
|
||||||
|
|
||||||
public class GameEventFlipCoin extends GameEvent {
|
public class GameEventFlipCoin extends GameEvent {
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> T visit(IGameEventVisitor<T> visitor) {
|
public <T> T visit(IGameEventVisitor<T> visitor) {
|
||||||
return visitor.visit(this);
|
return visitor.visit(this);
|
||||||
|
|||||||
@@ -12,8 +12,7 @@ public class GameEventGameOutcome extends GameEvent {
|
|||||||
this.result = lastOne;
|
this.result = lastOne;
|
||||||
this.history = history;
|
this.history = history;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> T visit(IGameEventVisitor<T> visitor) {
|
public <T> T visit(IGameEventVisitor<T> visitor) {
|
||||||
return visitor.visit(this);
|
return visitor.visit(this);
|
||||||
|
|||||||
@@ -9,12 +9,11 @@ import forge.game.player.Player;
|
|||||||
public class GameEventGameRestarted extends GameEvent {
|
public class GameEventGameRestarted extends GameEvent {
|
||||||
|
|
||||||
public final Player whoRestarted;
|
public final Player whoRestarted;
|
||||||
|
|
||||||
public GameEventGameRestarted(Player playerTurn) {
|
public GameEventGameRestarted(Player playerTurn) {
|
||||||
whoRestarted = playerTurn;
|
whoRestarted = playerTurn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> T visit(IGameEventVisitor<T> visitor) {
|
public <T> T visit(IGameEventVisitor<T> visitor) {
|
||||||
return visitor.visit(this);
|
return visitor.visit(this);
|
||||||
|
|||||||
@@ -22,12 +22,11 @@ public class GameEventGameStarted extends GameEvent {
|
|||||||
this.players = players;
|
this.players = players;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> T visit(IGameEventVisitor<T> visitor) {
|
public <T> T visit(IGameEventVisitor<T> visitor) {
|
||||||
return visitor.visit(this);
|
return visitor.visit(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see java.lang.Object#toString()
|
* @see java.lang.Object#toString()
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ public class GameEventLandPlayed extends GameEvent {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> T visit(IGameEventVisitor<T> visitor) {
|
public <T> T visit(IGameEventVisitor<T> visitor) {
|
||||||
return visitor.visit(this);
|
return visitor.visit(this);
|
||||||
|
|||||||
@@ -4,11 +4,11 @@ import forge.game.player.Player;
|
|||||||
|
|
||||||
// This special event denotes loss of mana due to phase end
|
// This special event denotes loss of mana due to phase end
|
||||||
public class GameEventManaBurn extends GameEvent {
|
public class GameEventManaBurn extends GameEvent {
|
||||||
|
|
||||||
public final Player player;
|
public final Player player;
|
||||||
public final boolean causedLifeLoss;
|
public final boolean causedLifeLoss;
|
||||||
public final int amount;
|
public final int amount;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO: Write javadoc for Constructor.
|
* TODO: Write javadoc for Constructor.
|
||||||
* @param dealDamage
|
* @param dealDamage
|
||||||
@@ -19,7 +19,7 @@ public class GameEventManaBurn extends GameEvent {
|
|||||||
amount = burn;
|
amount = burn;
|
||||||
causedLifeLoss = dealDamage;
|
causedLifeLoss = dealDamage;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> T visit(IGameEventVisitor<T> visitor) {
|
public <T> T visit(IGameEventVisitor<T> visitor) {
|
||||||
return visitor.visit(this);
|
return visitor.visit(this);
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ public class GameEventManaPool extends GameEvent {
|
|||||||
public <T> T visit(IGameEventVisitor<T> visitor) {
|
public <T> T visit(IGameEventVisitor<T> visitor) {
|
||||||
return visitor.visit(this);
|
return visitor.visit(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see java.lang.Object#toString()
|
* @see java.lang.Object#toString()
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -12,8 +12,7 @@ public class GameEventMulligan extends GameEvent {
|
|||||||
public GameEventMulligan(Player p) {
|
public GameEventMulligan(Player p) {
|
||||||
player = p;
|
player = p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> T visit(IGameEventVisitor<T> visitor) {
|
public <T> T visit(IGameEventVisitor<T> visitor) {
|
||||||
return visitor.visit(this);
|
return visitor.visit(this);
|
||||||
|
|||||||
@@ -8,18 +8,18 @@ public class GameEventPlayerLivesChanged extends GameEvent {
|
|||||||
public final Player player;
|
public final Player player;
|
||||||
public final int oldLives;
|
public final int oldLives;
|
||||||
public final int newLives;
|
public final int newLives;
|
||||||
|
|
||||||
public GameEventPlayerLivesChanged(Player who, int oldValue, int newValue) {
|
public GameEventPlayerLivesChanged(Player who, int oldValue, int newValue) {
|
||||||
player = who;
|
player = who;
|
||||||
oldLives = oldValue;
|
oldLives = oldValue;
|
||||||
newLives = newValue;
|
newLives = newValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> T visit(IGameEventVisitor<T> visitor) {
|
public <T> T visit(IGameEventVisitor<T> visitor) {
|
||||||
return visitor.visit(this);
|
return visitor.visit(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return TextUtil.concatWithSpace(Lang.getInstance().getPossesive(player.getName()),"lives changed:", String.valueOf(oldLives),"->", String.valueOf(newLives));
|
return TextUtil.concatWithSpace(Lang.getInstance().getPossesive(player.getName()),"lives changed:", String.valueOf(oldLives),"->", String.valueOf(newLives));
|
||||||
|
|||||||
@@ -19,8 +19,7 @@ public class GameEventPlayerPoisoned extends GameEvent {
|
|||||||
oldValue = old;
|
oldValue = old;
|
||||||
amount = num;
|
amount = num;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> T visit(IGameEventVisitor<T> visitor) {
|
public <T> T visit(IGameEventVisitor<T> visitor) {
|
||||||
return visitor.visit(this);
|
return visitor.visit(this);
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ public class GameEventPlayerPriority extends GameEvent {
|
|||||||
public final Player turn;
|
public final Player turn;
|
||||||
public final PhaseType phase;
|
public final PhaseType phase;
|
||||||
public final Player priority;
|
public final Player priority;
|
||||||
|
|
||||||
public GameEventPlayerPriority(Player playerTurn, PhaseType phase, Player priorityPlayer) {
|
public GameEventPlayerPriority(Player playerTurn, PhaseType phase, Player priorityPlayer) {
|
||||||
turn = playerTurn;
|
turn = playerTurn;
|
||||||
this.phase = phase;
|
this.phase = phase;
|
||||||
@@ -25,7 +25,6 @@ public class GameEventPlayerPriority extends GameEvent {
|
|||||||
return visitor.visit(this);
|
return visitor.visit(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see java.lang.Object#toString()
|
* @see java.lang.Object#toString()
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -3,10 +3,10 @@ package forge.game.event;
|
|||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
|
|
||||||
public class GameEventScry extends GameEvent {
|
public class GameEventScry extends GameEvent {
|
||||||
|
|
||||||
public final Player player;
|
public final Player player;
|
||||||
public final int toTop, toBottom;
|
public final int toTop, toBottom;
|
||||||
|
|
||||||
public GameEventScry(Player player, int toTop, int toBottom) {
|
public GameEventScry(Player player, int toTop, int toBottom) {
|
||||||
this.player = player;
|
this.player = player;
|
||||||
this.toTop = toTop;
|
this.toTop = toTop;
|
||||||
@@ -18,4 +18,3 @@ public class GameEventScry extends GameEvent {
|
|||||||
return visitor.visit(this);
|
return visitor.visit(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,9 +5,9 @@ import forge.util.Lang;
|
|||||||
import forge.util.TextUtil;
|
import forge.util.TextUtil;
|
||||||
|
|
||||||
public class GameEventShuffle extends GameEvent {
|
public class GameEventShuffle extends GameEvent {
|
||||||
|
|
||||||
public final Player player;
|
public final Player player;
|
||||||
|
|
||||||
public GameEventShuffle(Player player) {
|
public GameEventShuffle(Player player) {
|
||||||
this.player = player;
|
this.player = player;
|
||||||
}
|
}
|
||||||
@@ -16,7 +16,7 @@ public class GameEventShuffle extends GameEvent {
|
|||||||
public <T> T visit(IGameEventVisitor<T> visitor) {
|
public <T> T visit(IGameEventVisitor<T> visitor) {
|
||||||
return visitor.visit(this);
|
return visitor.visit(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see java.lang.Object#toString()
|
* @see java.lang.Object#toString()
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ public class GameEventSpellAbilityCast extends GameEvent {
|
|||||||
public final SpellAbilityStackInstance si;
|
public final SpellAbilityStackInstance si;
|
||||||
public final boolean replicate;
|
public final boolean replicate;
|
||||||
public final int stackIndex;
|
public final int stackIndex;
|
||||||
|
|
||||||
public GameEventSpellAbilityCast(SpellAbility sp, SpellAbilityStackInstance si, int stackIndex, boolean replicate) {
|
public GameEventSpellAbilityCast(SpellAbility sp, SpellAbilityStackInstance si, int stackIndex, boolean replicate) {
|
||||||
sa = sp;
|
sa = sp;
|
||||||
this.si = si;
|
this.si = si;
|
||||||
|
|||||||
@@ -23,8 +23,6 @@ public class GameEventSpellResolved extends GameEvent {
|
|||||||
this.hasFizzled = hasFizzled;
|
this.hasFizzled = hasFizzled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> T visit(IGameEventVisitor<T> visitor) {
|
public <T> T visit(IGameEventVisitor<T> visitor) {
|
||||||
return visitor.visit(this);
|
return visitor.visit(this);
|
||||||
|
|||||||
@@ -3,10 +3,10 @@ package forge.game.event;
|
|||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
|
|
||||||
public class GameEventSurveil extends GameEvent {
|
public class GameEventSurveil extends GameEvent {
|
||||||
|
|
||||||
public final Player player;
|
public final Player player;
|
||||||
public final int toLibrary, toGraveyard;
|
public final int toLibrary, toGraveyard;
|
||||||
|
|
||||||
public GameEventSurveil(Player player, int toLibrary, int toGraveyard) {
|
public GameEventSurveil(Player player, int toLibrary, int toGraveyard) {
|
||||||
this.player = player;
|
this.player = player;
|
||||||
this.toLibrary = toLibrary;
|
this.toLibrary = toLibrary;
|
||||||
@@ -18,4 +18,3 @@ public class GameEventSurveil extends GameEvent {
|
|||||||
return visitor.visit(this);
|
return visitor.visit(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
package forge.game.event;
|
package forge.game.event;
|
||||||
|
|
||||||
public class GameEventTokenCreated extends GameEvent {
|
public class GameEventTokenCreated extends GameEvent {
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> T visit(IGameEventVisitor<T> visitor) {
|
public <T> T visit(IGameEventVisitor<T> visitor) {
|
||||||
return visitor.visit(this);
|
return visitor.visit(this);
|
||||||
|
|||||||
@@ -4,10 +4,10 @@ import forge.game.player.Player;
|
|||||||
import forge.util.TextUtil;
|
import forge.util.TextUtil;
|
||||||
|
|
||||||
public class GameEventTurnBegan extends GameEvent {
|
public class GameEventTurnBegan extends GameEvent {
|
||||||
|
|
||||||
public final Player turnOwner;
|
public final Player turnOwner;
|
||||||
public final int turnNumber;
|
public final int turnNumber;
|
||||||
|
|
||||||
public GameEventTurnBegan(Player turnOwner, int turnNumber) {
|
public GameEventTurnBegan(Player turnOwner, int turnNumber) {
|
||||||
super();
|
super();
|
||||||
this.turnOwner = turnOwner;
|
this.turnOwner = turnOwner;
|
||||||
@@ -18,7 +18,7 @@ public class GameEventTurnBegan extends GameEvent {
|
|||||||
public <T> T visit(IGameEventVisitor<T> visitor) {
|
public <T> T visit(IGameEventVisitor<T> visitor) {
|
||||||
return visitor.visit(this);
|
return visitor.visit(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see java.lang.Object#toString()
|
* @see java.lang.Object#toString()
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
package forge.game.event;
|
package forge.game.event;
|
||||||
|
|
||||||
public class GameEventTurnEnded extends GameEvent {
|
public class GameEventTurnEnded extends GameEvent {
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> T visit(IGameEventVisitor<T> visitor) {
|
public <T> T visit(IGameEventVisitor<T> visitor) {
|
||||||
return visitor.visit(this);
|
return visitor.visit(this);
|
||||||
|
|||||||
@@ -105,4 +105,3 @@ public interface IGameEventVisitor<T> {
|
|||||||
public T visit(GameEventZone event) { return null; }
|
public T visit(GameEventZone event) { return null; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -152,8 +152,7 @@ public enum Keyword {
|
|||||||
SURGE("Surge", KeywordWithCost.class, false, "You may cast this spell for its surge cost if you or a teammate has cast another spell this turn."),
|
SURGE("Surge", KeywordWithCost.class, false, "You may cast this spell for its surge cost if you or a teammate has cast another spell this turn."),
|
||||||
SUSPEND("Suspend", Suspend.class, false, "Rather than cast this card from your hand, you may pay %s and exile it with {%d:time counter} on it. At the beginning of your upkeep, remove a time counter. When the last is removed, cast it without paying its mana cost."),
|
SUSPEND("Suspend", Suspend.class, false, "Rather than cast this card from your hand, you may pay %s and exile it with {%d:time counter} on it. At the beginning of your upkeep, remove a time counter. When the last is removed, cast it without paying its mana cost."),
|
||||||
TOTEM_ARMOR("Totem armor", SimpleKeyword.class, true, "If enchanted permanent would be destroyed, instead remove all damage marked on it and destroy this Aura."),
|
TOTEM_ARMOR("Totem armor", SimpleKeyword.class, true, "If enchanted permanent would be destroyed, instead remove all damage marked on it and destroy this Aura."),
|
||||||
TRAMPLE("Trample", SimpleKeyword.class, true, "This creature can deal excess combat damage to the player or planeswalker it's attacking."),
|
TRAMPLE("Trample", Trample.class, true, "This creature can deal excess combat damage to the player or planeswalker it's attacking."),
|
||||||
TRAMPLE_OVER_PLANESWALKERS("Trample over planeswalkers", SimpleKeyword.class, true, "This creature can deal excess combat damage to the controller of the planeswalker it’s attacking."),
|
|
||||||
TRANSFIGURE("Transfigure", KeywordWithCost.class, false, "%s, Sacrifice this creature: Search your library for a creature card with the same mana value as this creature and put that card onto the battlefield, then shuffle. Transfigure only as a sorcery."),
|
TRANSFIGURE("Transfigure", KeywordWithCost.class, false, "%s, Sacrifice this creature: Search your library for a creature card with the same mana value as this creature and put that card onto the battlefield, then shuffle. Transfigure only as a sorcery."),
|
||||||
TRANSMUTE("Transmute", KeywordWithCost.class, false, "%s, Discard this card: Search your library for a card with the same mana value as this card, reveal it, and put it into your hand, then shuffle. Transmute only as a sorcery."),
|
TRANSMUTE("Transmute", KeywordWithCost.class, false, "%s, Discard this card: Search your library for a card with the same mana value as this card, reveal it, and put it into your hand, then shuffle. Transmute only as a sorcery."),
|
||||||
TRIBUTE("Tribute", KeywordWithAmount.class, false, "As this creature enters the battlefield, an opponent of your choice may put {%d:+1/+1 counter} on it."),
|
TRIBUTE("Tribute", KeywordWithAmount.class, false, "As this creature enters the battlefield, an opponent of your choice may put {%d:+1/+1 counter} on it."),
|
||||||
|
|||||||
35
forge-game/src/main/java/forge/game/keyword/Trample.java
Normal file
35
forge-game/src/main/java/forge/game/keyword/Trample.java
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
package forge.game.keyword;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
public class Trample extends KeywordInstance<Trample> {
|
||||||
|
private String type = "";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void parse(String details) {
|
||||||
|
if (!details.isEmpty()) {
|
||||||
|
type = details.split(":")[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String formatReminderText(String reminderText) {
|
||||||
|
if (!type.isEmpty()) {
|
||||||
|
return "This creature can deal excess combat damage to the controller of the planeswalker it’s attacking.";
|
||||||
|
}
|
||||||
|
return reminderText;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see forge.game.keyword.KeywordInstance#redundant(java.util.Collection)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean redundant(Collection<KeywordInterface> list) {
|
||||||
|
for (KeywordInterface i : list) {
|
||||||
|
if (i.getOriginal().equals(getOriginal())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -20,8 +20,10 @@ package forge.game.mana;
|
|||||||
import forge.card.MagicColor;
|
import forge.card.MagicColor;
|
||||||
import forge.card.mana.ManaAtom;
|
import forge.card.mana.ManaAtom;
|
||||||
import forge.game.card.Card;
|
import forge.game.card.Card;
|
||||||
|
import forge.game.card.CardUtil;
|
||||||
import forge.game.spellability.AbilityManaPart;
|
import forge.game.spellability.AbilityManaPart;
|
||||||
import forge.game.spellability.SpellAbility;
|
import forge.game.spellability.SpellAbility;
|
||||||
|
import forge.game.zone.ZoneType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
@@ -71,7 +73,7 @@ public class Mana {
|
|||||||
public Mana(final byte color, final Card source, final AbilityManaPart manaAbility) {
|
public Mana(final byte color, final Card source, final AbilityManaPart manaAbility) {
|
||||||
this.color = color;
|
this.color = color;
|
||||||
this.manaAbility = manaAbility;
|
this.manaAbility = manaAbility;
|
||||||
this.sourceCard = source;
|
this.sourceCard = source.isInZone(ZoneType.Battlefield) ? CardUtil.getLKICopy(source) : source.getGame().getChangeZoneLKIInfo(source);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -3221,21 +3221,21 @@ public class Player extends GameEntity implements Comparable<Player> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void updateKeywordCardAbilityText() {
|
public void updateKeywordCardAbilityText() {
|
||||||
if(getKeywordCard() == null)
|
if (getKeywordCard() == null)
|
||||||
return;
|
return;
|
||||||
final PlayerZone com = getZone(ZoneType.Command);
|
final PlayerZone com = getZone(ZoneType.Command);
|
||||||
keywordEffect.setText("");
|
keywordEffect.setText("");
|
||||||
keywordEffect.updateAbilityTextForView();
|
keywordEffect.updateAbilityTextForView();
|
||||||
boolean headerAdded = false;
|
boolean headerAdded = false;
|
||||||
StringBuilder kw = new StringBuilder();
|
StringBuilder kw = new StringBuilder();
|
||||||
for(KeywordInterface k : keywords) {
|
for (KeywordInterface k : keywords) {
|
||||||
if(!headerAdded) {
|
if (!headerAdded) {
|
||||||
headerAdded = true;
|
headerAdded = true;
|
||||||
kw.append(this.getName()).append(" has: \n");
|
kw.append(this.getName()).append(" has: \n");
|
||||||
}
|
}
|
||||||
kw.append(k).append("\n");
|
kw.append(k).append("\n");
|
||||||
}
|
}
|
||||||
if(!kw.toString().isEmpty()) {
|
if (!kw.toString().isEmpty()) {
|
||||||
keywordEffect.setText(trimKeywords(kw.toString()));
|
keywordEffect.setText(trimKeywords(kw.toString()));
|
||||||
keywordEffect.updateAbilityTextForView();
|
keywordEffect.updateAbilityTextForView();
|
||||||
}
|
}
|
||||||
@@ -3275,7 +3275,7 @@ public class Player extends GameEntity implements Comparable<Player> {
|
|||||||
|
|
||||||
final PlayerZone com = getZone(ZoneType.Command);
|
final PlayerZone com = getZone(ZoneType.Command);
|
||||||
|
|
||||||
if(bless) {
|
if (bless) {
|
||||||
blessingEffect = new Card(game.nextCardId(), null, game);
|
blessingEffect = new Card(game.nextCardId(), null, game);
|
||||||
blessingEffect.setOwner(this);
|
blessingEffect.setOwner(this);
|
||||||
blessingEffect.setImageKey("t:blessing");
|
blessingEffect.setImageKey("t:blessing");
|
||||||
@@ -3337,7 +3337,6 @@ public class Player extends GameEntity implements Comparable<Player> {
|
|||||||
}
|
}
|
||||||
return targetPlayer == null || !targetPlayer.equals(sa.getActivatingPlayer())
|
return targetPlayer == null || !targetPlayer.equals(sa.getActivatingPlayer())
|
||||||
|| !hasKeyword("Spells and abilities you control can't cause you to search your library.");
|
|| !hasKeyword("Spells and abilities you control can't cause you to search your library.");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Card getKeywordCard() {
|
public Card getKeywordCard() {
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ public abstract class AbilityActivated extends SpellAbility implements Cloneable
|
|||||||
this.setTargetRestrictions(tgt);
|
this.setTargetRestrictions(tgt);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isActivatedAbility() { return true; }
|
public boolean isActivatedAbility() { return !isTrigger(); }
|
||||||
|
|
||||||
/** {@inheritDoc} */
|
/** {@inheritDoc} */
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ import com.google.common.collect.Sets;
|
|||||||
|
|
||||||
import forge.game.Game;
|
import forge.game.Game;
|
||||||
import forge.game.GameEntity;
|
import forge.game.GameEntity;
|
||||||
|
import forge.game.GameStage;
|
||||||
import forge.game.IHasSVars;
|
import forge.game.IHasSVars;
|
||||||
import forge.game.TriggerReplacementBase;
|
import forge.game.TriggerReplacementBase;
|
||||||
import forge.game.ability.AbilityFactory;
|
import forge.game.ability.AbilityFactory;
|
||||||
@@ -347,8 +348,9 @@ public abstract class Trigger extends TriggerReplacementBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// host controller will be null when adding card in a simulation game
|
// host controller will be null when adding card in a simulation game
|
||||||
if (this.getHostCard().getController() == null || !meetsCommonRequirements(this.mapParams))
|
if (this.getHostCard().getController() == null || game.getAge() != GameStage.Play || !meetsCommonRequirements(this.mapParams)) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,7 +52,6 @@ public class TriggerAbandoned extends Trigger {
|
|||||||
* @param runParams*/
|
* @param runParams*/
|
||||||
@Override
|
@Override
|
||||||
public final boolean performTest(final Map<AbilityKey, Object> runParams) {
|
public final boolean performTest(final Map<AbilityKey, Object> runParams) {
|
||||||
|
|
||||||
if (!matchesValidParam("ValidCard", runParams.get(AbilityKey.Scheme))) {
|
if (!matchesValidParam("ValidCard", runParams.get(AbilityKey.Scheme))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -60,7 +59,6 @@ public class TriggerAbandoned extends Trigger {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** {@inheritDoc} */
|
/** {@inheritDoc} */
|
||||||
@Override
|
@Override
|
||||||
public final void setTriggeringObjects(final SpellAbility sa, Map<AbilityKey, Object> runParams) {
|
public final void setTriggeringObjects(final SpellAbility sa, Map<AbilityKey, Object> runParams) {
|
||||||
@@ -72,4 +70,3 @@ public class TriggerAbandoned extends Trigger {
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -63,7 +63,6 @@ public class TriggerAttached extends Trigger {
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** {@inheritDoc} */
|
/** {@inheritDoc} */
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -54,7 +54,6 @@ public class TriggerAttackerUnblocked extends Trigger {
|
|||||||
* @param runParams*/
|
* @param runParams*/
|
||||||
@Override
|
@Override
|
||||||
public final boolean performTest(final Map<AbilityKey, Object> runParams) {
|
public final boolean performTest(final Map<AbilityKey, Object> runParams) {
|
||||||
|
|
||||||
if (!matchesValidParam("ValidCard", runParams.get(AbilityKey.Attacker))) {
|
if (!matchesValidParam("ValidCard", runParams.get(AbilityKey.Attacker))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,7 +57,6 @@ public class TriggerAttacks extends Trigger {
|
|||||||
* @param runParams*/
|
* @param runParams*/
|
||||||
@Override
|
@Override
|
||||||
public final boolean performTest(final Map<AbilityKey, Object> runParams) {
|
public final boolean performTest(final Map<AbilityKey, Object> runParams) {
|
||||||
|
|
||||||
if (!matchesValidParam("ValidCard", runParams.get(AbilityKey.Attacker))) {
|
if (!matchesValidParam("ValidCard", runParams.get(AbilityKey.Attacker))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,7 +55,6 @@ public class TriggerChampioned extends Trigger {
|
|||||||
* @param runParams*/
|
* @param runParams*/
|
||||||
@Override
|
@Override
|
||||||
public final boolean performTest(final Map<AbilityKey, Object> runParams) {
|
public final boolean performTest(final Map<AbilityKey, Object> runParams) {
|
||||||
|
|
||||||
if (!matchesValidParam("ValidCard", runParams.get(AbilityKey.Championed))) {
|
if (!matchesValidParam("ValidCard", runParams.get(AbilityKey.Championed))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ public class TriggerDamageAll extends Trigger {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean performTest(Map<AbilityKey, Object> runParams) {
|
public boolean performTest(Map<AbilityKey, Object> runParams) {
|
||||||
|
|
||||||
if (hasParam("CombatDamage")) {
|
if (hasParam("CombatDamage")) {
|
||||||
if (getParam("CombatDamage").equals("True")) {
|
if (getParam("CombatDamage").equals("True")) {
|
||||||
if (!((Boolean) runParams.get(AbilityKey.IsCombatDamage))) {
|
if (!((Boolean) runParams.get(AbilityKey.IsCombatDamage))) {
|
||||||
|
|||||||
@@ -59,7 +59,6 @@ public class TriggerDamageDealtOnce extends Trigger {
|
|||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@Override
|
@Override
|
||||||
public final boolean performTest(final Map<AbilityKey, Object> runParams) {
|
public final boolean performTest(final Map<AbilityKey, Object> runParams) {
|
||||||
|
|
||||||
if (hasParam("CombatDamage")) {
|
if (hasParam("CombatDamage")) {
|
||||||
if (getParam("CombatDamage").equals("True")) {
|
if (getParam("CombatDamage").equals("True")) {
|
||||||
if (!((Boolean) runParams.get(AbilityKey.IsCombatDamage))) {
|
if (!((Boolean) runParams.get(AbilityKey.IsCombatDamage))) {
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ public class TriggerDamageDoneOnce extends Trigger {
|
|||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@Override
|
@Override
|
||||||
public boolean performTest(Map<AbilityKey, Object> runParams) {
|
public boolean performTest(Map<AbilityKey, Object> runParams) {
|
||||||
|
|
||||||
if (hasParam("CombatDamage")) {
|
if (hasParam("CombatDamage")) {
|
||||||
if (getParam("CombatDamage").equals("True")) {
|
if (getParam("CombatDamage").equals("True")) {
|
||||||
if (!((Boolean) runParams.get(AbilityKey.IsCombatDamage))) {
|
if (!((Boolean) runParams.get(AbilityKey.IsCombatDamage))) {
|
||||||
@@ -54,7 +53,11 @@ public class TriggerDamageDoneOnce extends Trigger {
|
|||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
final Map<Card, Integer> damageMap = (Map<Card, Integer>) runParams.get(AbilityKey.DamageMap);
|
final Map<Card, Integer> damageMap = (Map<Card, Integer>) runParams.get(AbilityKey.DamageMap);
|
||||||
|
|
||||||
sa.setTriggeringObject(AbilityKey.Target, CardUtil.getLKICopy((Card)runParams.get(AbilityKey.DamageTarget)));
|
Object target = runParams.get(AbilityKey.DamageTarget);
|
||||||
|
if (target instanceof Card) {
|
||||||
|
target = CardUtil.getLKICopy((Card)runParams.get(AbilityKey.DamageTarget));
|
||||||
|
}
|
||||||
|
sa.setTriggeringObject(AbilityKey.Target, target);
|
||||||
sa.setTriggeringObject(AbilityKey.Sources, getDamageSources(damageMap));
|
sa.setTriggeringObject(AbilityKey.Sources, getDamageSources(damageMap));
|
||||||
sa.setTriggeringObject(AbilityKey.DamageAmount, getDamageAmount(damageMap));
|
sa.setTriggeringObject(AbilityKey.DamageAmount, getDamageAmount(damageMap));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,7 +56,6 @@ public class TriggerDamagePrevented extends Trigger {
|
|||||||
* @param runParams*/
|
* @param runParams*/
|
||||||
@Override
|
@Override
|
||||||
public final boolean performTest(final Map<AbilityKey, Object> runParams) {
|
public final boolean performTest(final Map<AbilityKey, Object> runParams) {
|
||||||
|
|
||||||
if (!matchesValidParam("ValidSource", runParams.get(AbilityKey.DamageSource))) {
|
if (!matchesValidParam("ValidSource", runParams.get(AbilityKey.DamageSource))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,7 +55,6 @@ public class TriggerDamagePreventedOnce extends Trigger {
|
|||||||
* @param runParams*/
|
* @param runParams*/
|
||||||
@Override
|
@Override
|
||||||
public final boolean performTest(final Map<AbilityKey, Object> runParams) {
|
public final boolean performTest(final Map<AbilityKey, Object> runParams) {
|
||||||
|
|
||||||
if (!matchesValidParam("ValidTarget", runParams.get(AbilityKey.DamageTarget))) {
|
if (!matchesValidParam("ValidTarget", runParams.get(AbilityKey.DamageTarget))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -82,4 +82,3 @@ public class TriggerExcessDamage extends Trigger {
|
|||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -55,7 +55,6 @@ public class TriggerExploited extends Trigger {
|
|||||||
* @param runParams*/
|
* @param runParams*/
|
||||||
@Override
|
@Override
|
||||||
public final boolean performTest(final Map<AbilityKey, Object> runParams) {
|
public final boolean performTest(final Map<AbilityKey, Object> runParams) {
|
||||||
|
|
||||||
if (!matchesValidParam("ValidCard", runParams.get(AbilityKey.Exploited))) {
|
if (!matchesValidParam("ValidCard", runParams.get(AbilityKey.Exploited))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -73,4 +73,3 @@ public class TriggerExplores extends Trigger {
|
|||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -70,4 +70,3 @@ public class TriggerFightOnce extends Trigger {
|
|||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -579,7 +579,7 @@ public class TriggerHandler {
|
|||||||
sa.setOptionalTrigger(true);
|
sa.setOptionalTrigger(true);
|
||||||
decider = AbilityUtils.getDefinedPlayers(host, regtrig.getParam("OptionalDecider"), sa).get(0);
|
decider = AbilityUtils.getDefinedPlayers(host, regtrig.getParam("OptionalDecider"), sa).get(0);
|
||||||
}
|
}
|
||||||
else if (sa instanceof AbilitySub || !sa.hasParam("Cost") || sa.getParam("Cost").equals("0")) {
|
else if (sa instanceof AbilitySub || !sa.hasParam("Cost") || (sa.getPayCosts() != null && sa.getPayCosts().isMandatory()) || sa.getParam("Cost").equals("0")) {
|
||||||
isMandatory = true;
|
isMandatory = true;
|
||||||
} else { // triggers with a cost can't be mandatory
|
} else { // triggers with a cost can't be mandatory
|
||||||
sa.setOptionalTrigger(true);
|
sa.setOptionalTrigger(true);
|
||||||
|
|||||||
@@ -67,7 +67,6 @@ public class TriggerPayCumulativeUpkeep extends Trigger {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** {@inheritDoc} */
|
/** {@inheritDoc} */
|
||||||
@Override
|
@Override
|
||||||
public final void setTriggeringObjects(final SpellAbility sa, Map<AbilityKey, Object> runParams) {
|
public final void setTriggeringObjects(final SpellAbility sa, Map<AbilityKey, Object> runParams) {
|
||||||
|
|||||||
@@ -66,7 +66,6 @@ public class TriggerPayEcho extends Trigger {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** {@inheritDoc} */
|
/** {@inheritDoc} */
|
||||||
@Override
|
@Override
|
||||||
public final void setTriggeringObjects(final SpellAbility sa, Map<AbilityKey, Object> runParams) {
|
public final void setTriggeringObjects(final SpellAbility sa, Map<AbilityKey, Object> runParams) {
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ public class TriggerPhaseOut extends Trigger {
|
|||||||
* @param runParams*/
|
* @param runParams*/
|
||||||
@Override
|
@Override
|
||||||
public final boolean performTest(final Map<AbilityKey, Object> runParams) {
|
public final boolean performTest(final Map<AbilityKey, Object> runParams) {
|
||||||
|
|
||||||
if (!matchesValidParam("ValidCard", runParams.get(AbilityKey.Card))) {
|
if (!matchesValidParam("ValidCard", runParams.get(AbilityKey.Card))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -116,7 +116,6 @@ public class TriggerSacrificed extends Trigger {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** {@inheritDoc} */
|
/** {@inheritDoc} */
|
||||||
@Override
|
@Override
|
||||||
public final void setTriggeringObjects(final SpellAbility sa, Map<AbilityKey, Object> runParams) {
|
public final void setTriggeringObjects(final SpellAbility sa, Map<AbilityKey, Object> runParams) {
|
||||||
|
|||||||
@@ -61,7 +61,6 @@ public class TriggerScry extends Trigger {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** {@inheritDoc} */
|
/** {@inheritDoc} */
|
||||||
@Override
|
@Override
|
||||||
public final void setTriggeringObjects(final SpellAbility sa, Map<AbilityKey, Object> runParams) {
|
public final void setTriggeringObjects(final SpellAbility sa, Map<AbilityKey, Object> runParams) {
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user