From b3a2aab6e583b1e6dd2a788e1cb79a3ba0caf4f6 Mon Sep 17 00:00:00 2001 From: Sloth Date: Mon, 4 Mar 2013 18:36:28 +0000 Subject: [PATCH 01/11] - Fixed mandatory targets not being enforced for the human. --- .../card/spellability/TargetSelection.java | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/main/java/forge/card/spellability/TargetSelection.java b/src/main/java/forge/card/spellability/TargetSelection.java index f6d61793f33..d3f228f6084 100644 --- a/src/main/java/forge/card/spellability/TargetSelection.java +++ b/src/main/java/forge/card/spellability/TargetSelection.java @@ -411,13 +411,19 @@ public class TargetSelection { // If reached Minimum targets, enable OK button if (!tgt.isMinTargetsChosen(sa.getSourceCard(), sa) || tgt.isDividedAsYouChoose()) { - ButtonUtil.enableOnlyCancel(); + if (mandatory && tgt.hasCandidates(sa, true)) { + // Player has to click on a target + ButtonUtil.disableAll(); + } else { + ButtonUtil.enableOnlyCancel(); + } } else { - ButtonUtil.enableAllFocusOk(); - } - - if (mandatory && tgt.hasCandidates(sa, true)) { - ButtonUtil.enableOnlyOk(); + if (mandatory && tgt.hasCandidates(sa, true)) { + // Player has to click on a target or ok + ButtonUtil.enableOnlyOk(); + } else { + ButtonUtil.enableAllFocusOk(); + } } } From 3517416a5a627094bdf7577c0b8e3c18b9e3ef7f Mon Sep 17 00:00:00 2001 From: Maxmtg Date: Mon, 4 Mar 2013 19:29:52 +0000 Subject: [PATCH 02/11] Added commander arsenal setinfo (CM1) --- res/cardsfolder/c/chaos_warp.txt | 3 ++- res/cardsfolder/d/decree_of_pain.txt | 3 ++- res/cardsfolder/d/desertion.txt | 3 ++- res/cardsfolder/d/dragonlair_spider.txt | 3 ++- res/cardsfolder/d/duplicant.txt | 3 ++- res/cardsfolder/e/edric_spymaster_of_trest.txt | 3 ++- res/cardsfolder/k/kaalia_of_the_vast.txt | 3 ++- res/cardsfolder/l/loyal_retainers.txt | 3 ++- res/cardsfolder/m/maelstrom_wanderer.txt | 3 ++- res/cardsfolder/m/minds_eye.txt | 3 ++- res/cardsfolder/m/miraris_wake.txt | 1 + res/cardsfolder/r/rhystic_study.txt | 3 ++- res/cardsfolder/s/scroll_rack.txt | 3 ++- res/cardsfolder/s/sylvan_library.txt | 1 + res/cardsfolder/t/the_mimeoplasm.txt | 3 ++- res/cardsfolder/v/vela_the_night_clad.txt | 3 ++- 16 files changed, 30 insertions(+), 14 deletions(-) diff --git a/res/cardsfolder/c/chaos_warp.txt b/res/cardsfolder/c/chaos_warp.txt index aea15c32e4d..74da46a7d6e 100644 --- a/res/cardsfolder/c/chaos_warp.txt +++ b/res/cardsfolder/c/chaos_warp.txt @@ -5,4 +5,5 @@ A:SP$ ChangeZone | Cost$ 2 R | Origin$ Battlefield | Destination$ Library | Vali SVar:DBDig:DB$Dig | Defined$ TargetedController | DigNum$ 1 | Reveal$ True | DestinationZone$ Battlefield | DestinationZone2$ Library | LibraryPosition2$ 0 | ChangeNum$ All | ChangeValid$ Permanent SVar:Picture:http://www.wizards.com/global/images/magic/general/chaos_warp.jpg Oracle:The owner of target permanent shuffles it into his or her library, then reveals the top card of his or her library. If it's a permanent card, he or she puts it onto the battlefield. -SetInfo:COM Rare \ No newline at end of file +SetInfo:COM Rare +SetInfo:CM1 Rare \ No newline at end of file diff --git a/res/cardsfolder/d/decree_of_pain.txt b/res/cardsfolder/d/decree_of_pain.txt index 60718ecb317..4c185d32090 100644 --- a/res/cardsfolder/d/decree_of_pain.txt +++ b/res/cardsfolder/d/decree_of_pain.txt @@ -11,4 +11,5 @@ SVar:DecreeX:Remembered$Amount SVar:RemAIDeck:True SVar:Picture:http://www.wizards.com/global/images/magic/general/decree_of_pain.jpg Oracle:Destroy all creatures. They can't be regenerated. Draw a card for each creature destroyed this way.\nCycling {3}{B}{B} ({3}{B}{B}, Discard this card: Draw a card.)\nWhen you cycle Decree of Pain, all creatures get -2/-2 until end of turn. -SetInfo:SCG Rare \ No newline at end of file +SetInfo:SCG Rare +SetInfo:CM1 Rare \ No newline at end of file diff --git a/res/cardsfolder/d/desertion.txt b/res/cardsfolder/d/desertion.txt index b5c52072490..13751d71945 100644 --- a/res/cardsfolder/d/desertion.txt +++ b/res/cardsfolder/d/desertion.txt @@ -7,4 +7,5 @@ SVar:X:Targeted$Valid Artifact,Creature SVar:Picture:http://www.wizards.com/global/images/magic/general/desertion.jpg Oracle:Counter target spell. If an artifact or creature spell is countered this way, put that card onto the battlefield under your control instead of into its owner's graveyard. SetInfo:VIS Rare -SetInfo:6ED Rare \ No newline at end of file +SetInfo:6ED Rare +SetInfo:CM1 Rare \ No newline at end of file diff --git a/res/cardsfolder/d/dragonlair_spider.txt b/res/cardsfolder/d/dragonlair_spider.txt index a828624da88..d920fb21bde 100644 --- a/res/cardsfolder/d/dragonlair_spider.txt +++ b/res/cardsfolder/d/dragonlair_spider.txt @@ -7,4 +7,5 @@ T:Mode$ SpellCast | ValidCard$ Card | ValidActivatingPlayer$ Opponent | TriggerZ SVar:TrigToken:AB$Token | Cost$ 0 | TokenAmount$ 1 | TokenName$ Insect | TokenTypes$ Creature,Insect | TokenOwner$ You | TokenColors$ Green | TokenPower$ 1 | TokenToughness$ 1 SVar:Picture:http://www.wizards.com/global/images/magic/general/dragonlair_spider.jpg Oracle:Reach\nWhenever an opponent casts a spell, put a 1/1 green Insect creature token onto the battlefield. -SetInfo:PC2 Rare \ No newline at end of file +SetInfo:PC2 Rare +SetInfo:CM1 Rare \ No newline at end of file diff --git a/res/cardsfolder/d/duplicant.txt b/res/cardsfolder/d/duplicant.txt index 0ed05bc626c..995880dae3a 100644 --- a/res/cardsfolder/d/duplicant.txt +++ b/res/cardsfolder/d/duplicant.txt @@ -14,4 +14,5 @@ SVar:Z:Imprinted$Valid Creature SVar:Picture:http://www.wizards.com/global/images/magic/general/duplicant.jpg Oracle:Imprint - When Duplicant enters the battlefield, you may exile target nontoken creature.\nAs long as the exiled card is a creature card, Duplicant has that card's power, toughness, and creature types. It's still a Shapeshifter. SetInfo:MRD Rare -SetInfo:ARC Rare \ No newline at end of file +SetInfo:ARC Rare +SetInfo:CM1 Rare \ No newline at end of file diff --git a/res/cardsfolder/e/edric_spymaster_of_trest.txt b/res/cardsfolder/e/edric_spymaster_of_trest.txt index 7a0fd3f1ed6..bea90755f2b 100644 --- a/res/cardsfolder/e/edric_spymaster_of_trest.txt +++ b/res/cardsfolder/e/edric_spymaster_of_trest.txt @@ -7,4 +7,5 @@ SVar:TrigDraw:AB$ Draw | Cost$ 0 | NumCards$ 1 | Defined$ TriggeredSourceControl SVar:PlayMain1:TRUE SVar:Picture:http://www.wizards.com/global/images/magic/general/edric_spymaster_of_trest.jpg Oracle:Whenever a creature deals combat damage to one of your opponents, its controller may draw a card. -SetInfo:COM Rare \ No newline at end of file +SetInfo:COM Rare +SetInfo:CM1 Rare \ No newline at end of file diff --git a/res/cardsfolder/k/kaalia_of_the_vast.txt b/res/cardsfolder/k/kaalia_of_the_vast.txt index 0644cc02f84..4858faea536 100644 --- a/res/cardsfolder/k/kaalia_of_the_vast.txt +++ b/res/cardsfolder/k/kaalia_of_the_vast.txt @@ -7,4 +7,5 @@ T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigChange | TriggerZones$ Bat SVar:TrigChange:AB$ChangeZone | Cost$ 0 | Origin$ Hand | Destination$ Battlefield | ChangeType$ Creature.Angel+YouCtrl,Creature.Demon+YouCtrl,Creature.Dragon+YouCtrl | Tapped$ True | Attacking$ True SVar:Picture:http://www.wizards.com/global/images/magic/general/kaalia_of_the_vast.jpg Oracle:Flying\nWhenever Kaalia of the Vast attacks an opponent, you may put an Angel, Demon, or Dragon creature card from your hand onto the battlefield tapped and attacking that opponent. -SetInfo:COM Mythic \ No newline at end of file +SetInfo:COM Mythic +SetInfo:CM1 Mythic \ No newline at end of file diff --git a/res/cardsfolder/l/loyal_retainers.txt b/res/cardsfolder/l/loyal_retainers.txt index 18049ed1f2f..6a1c0134395 100644 --- a/res/cardsfolder/l/loyal_retainers.txt +++ b/res/cardsfolder/l/loyal_retainers.txt @@ -5,4 +5,5 @@ PT:1/1 A:AB$ ChangeZone | Cost$ Sac<1/CARDNAME> | Origin$ Graveyard | Destination$ Battlefield | ValidTgts$ Creature.Legendary+YouCtrl | TgtPrompt$ Select a target legendary creature card from your graveyard | ChangeNum$ 1 | PlayerTurn$ True | ActivationPhases$ Upkeep->BeginCombat | SpellDescription$ Return target legendary creature card from your graveyard to the battlefield. Activate this ability only during your turn, before attackers are declared. SVar:Picture:http://www.wizards.com/global/images/magic/general/loyal_retainers.jpg Oracle:Sacrifice Loyal Retainers: Return target legendary creature card from your graveyard to the battlefield. Activate this ability only during your turn, before attackers are declared. -SetInfo:PTK Uncommon \ No newline at end of file +SetInfo:PTK Uncommon +SetInfo:CM1 Uncommon \ No newline at end of file diff --git a/res/cardsfolder/m/maelstrom_wanderer.txt b/res/cardsfolder/m/maelstrom_wanderer.txt index 3da19015f7a..9a7f944d3a5 100644 --- a/res/cardsfolder/m/maelstrom_wanderer.txt +++ b/res/cardsfolder/m/maelstrom_wanderer.txt @@ -7,4 +7,5 @@ K:Cascade S:Mode$ Continuous | Affected$ Creature.YouCtrl | AddKeyword$ Haste | Description$ Creatures you control have haste. SVar:Picture:http://www.wizards.com/global/images/magic/general/maelstrom_wanderer.jpg Oracle:Creatures you control have haste.\nCascade, cascade (When you cast this spell, exile cards from the top of your library until you exile a nonland card that costs less. You may cast it without paying its mana cost. Put the exiled cards on the bottom in a random order. Then do it again.) -SetInfo:PC2 Mythic \ No newline at end of file +SetInfo:PC2 Mythic +SetInfo:CM1 Mythic \ No newline at end of file diff --git a/res/cardsfolder/m/minds_eye.txt b/res/cardsfolder/m/minds_eye.txt index 011bf66e7ec..9513697b742 100644 --- a/res/cardsfolder/m/minds_eye.txt +++ b/res/cardsfolder/m/minds_eye.txt @@ -5,4 +5,5 @@ T:Mode$ Drawn | ValidCard$ Card.OppOwn | TriggerZones$ Battlefield | OptionalDec SVar:TrigDraw:AB$Draw | Cost$ 1 | Defined$ You | NumCards$ 1 SVar:Picture:http://www.wizards.com/global/images/magic/general/minds_eye.jpg Oracle:Whenever an opponent draws a card, you may pay {1}. If you do, draw a card. -SetInfo:MRD Rare \ No newline at end of file +SetInfo:MRD Rare +SetInfo:CM1 Rare \ No newline at end of file diff --git a/res/cardsfolder/m/miraris_wake.txt b/res/cardsfolder/m/miraris_wake.txt index 3b04f20f3e0..a0e0fc4e6cb 100644 --- a/res/cardsfolder/m/miraris_wake.txt +++ b/res/cardsfolder/m/miraris_wake.txt @@ -6,4 +6,5 @@ T:Mode$ TapsForMana | ValidCard$ Land.YouCtrl | Execute$ TrigMana | TriggerZones SVar:TrigMana:AB$ManaReflected | Cost$ 0 | ColorOrType$ Type | Valid$ Defined.Triggered | ReflectProperty$ Produced | Defined$ TriggeredPlayer SVar:Picture:http://www.wizards.com/global/images/magic/general/miraris_wake.jpg Oracle:Creatures you control get +1/+1.\nWhenever you tap a land for mana, add one mana to your mana pool of any type that land produced. +SetInfo:CM1 Rare SetInfo:JUD Rare \ No newline at end of file diff --git a/res/cardsfolder/r/rhystic_study.txt b/res/cardsfolder/r/rhystic_study.txt index 8f31b7c9563..99dc2d11826 100644 --- a/res/cardsfolder/r/rhystic_study.txt +++ b/res/cardsfolder/r/rhystic_study.txt @@ -5,4 +5,5 @@ T:Mode$ SpellCast | ValidCard$ Card | ValidActivatingPlayer$ Opponent | TriggerZ SVar:TrigDraw:AB$Draw | Cost$ 0 | Defined$ You | UnlessCost$ 1 | UnlessPayer$ TriggeredPlayer | NumCards$ 1 SVar:Picture:http://www.wizards.com/global/images/magic/general/rhystic_study.jpg Oracle:Whenever an opponent casts a spell, you may draw a card unless that player pays {1}. -SetInfo:PCY Common \ No newline at end of file +SetInfo:PCY Common +SetInfo:CM1 Common \ No newline at end of file diff --git a/res/cardsfolder/s/scroll_rack.txt b/res/cardsfolder/s/scroll_rack.txt index fa6c9769901..cda09e1d5e8 100644 --- a/res/cardsfolder/s/scroll_rack.txt +++ b/res/cardsfolder/s/scroll_rack.txt @@ -4,4 +4,5 @@ Types:Artifact SVar:RemAIDeck:True SVar:Picture:http://www.wizards.com/global/images/magic/general/scroll_rack.jpg Oracle:{1}, {T}: Exile any number of cards from your hand face down. Put that many cards from the top of your library into your hand. Then look at the exiled cards and put them on top of your library in any order. -SetInfo:TMP Rare \ No newline at end of file +SetInfo:TMP Rare +SetInfo:CM1 Rare \ No newline at end of file diff --git a/res/cardsfolder/s/sylvan_library.txt b/res/cardsfolder/s/sylvan_library.txt index efbc921ae16..8edff78064c 100644 --- a/res/cardsfolder/s/sylvan_library.txt +++ b/res/cardsfolder/s/sylvan_library.txt @@ -12,4 +12,5 @@ SVar:Picture:http://www.wizards.com/global/images/magic/general/sylvan_library.j Oracle:At the beginning of your draw step, you may draw two additional cards. If you do, choose two cards in your hand drawn this turn. For each of those cards, pay 4 life or put the card on top of your library. SetInfo:5ED Rare SetInfo:LEG Uncommon +SetInfo:CM1 Rare SetInfo:4ED Rare \ No newline at end of file diff --git a/res/cardsfolder/t/the_mimeoplasm.txt b/res/cardsfolder/t/the_mimeoplasm.txt index 5d1a7ed5907..f4fa743fd6f 100644 --- a/res/cardsfolder/t/the_mimeoplasm.txt +++ b/res/cardsfolder/t/the_mimeoplasm.txt @@ -16,4 +16,5 @@ SVar:MimeoX:Remembered$CardPower SVar:NeedsToPlayVar:MimeoInYard GE2 SVar:Picture:http://www.wizards.com/global/images/magic/general/the_mimeoplasm.jpg Oracle:As The Mimeoplasm enters the battlefield, you may exile two creature cards from graveyards. If you do, it enters the battlefield as a copy of one of those cards with a number of additional +1/+1 counters on it equal to the power of the other card. -SetInfo:COM Mythic \ No newline at end of file +SetInfo:COM Mythic +SetInfo:CM1 Mythic \ No newline at end of file diff --git a/res/cardsfolder/v/vela_the_night_clad.txt b/res/cardsfolder/v/vela_the_night_clad.txt index 5725c72e390..4abcfb61e5d 100644 --- a/res/cardsfolder/v/vela_the_night_clad.txt +++ b/res/cardsfolder/v/vela_the_night_clad.txt @@ -9,4 +9,5 @@ T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Any | ValidCard$ Creatu SVar:TrigLoseLife:AB$ LoseLife | Cost$ 0 | Defined$ Player.Opponent | LifeAmount$ 1 SVar:Picture:http://www.wizards.com/global/images/magic/general/vela_the_night_clad.jpg Oracle:Intimidate\nOther creatures you control have intimidate.\nWhenever Vela the Night-Clad or another creature you control leaves the battlefield, each opponent loses 1 life. -SetInfo:PC2 Mythic \ No newline at end of file +SetInfo:PC2 Mythic +SetInfo:CM1 Mythic \ No newline at end of file From 58fc1ae52a4fedc7f0b64cfb255717614c28ce74 Mon Sep 17 00:00:00 2001 From: Maxmtg Date: Mon, 4 Mar 2013 19:38:05 +0000 Subject: [PATCH 03/11] since mtgdata.txt is a bit broken now (lacks Assault but has 2 Batteries), the script will try to use 2nd part of a card to get rarities, CM1 set enabled to fill SetInfos --- res/assignSetInfo.py | 9 ++++++++- res/mtgdata-sets-to-forge.txt | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/res/assignSetInfo.py b/res/assignSetInfo.py index f398074d412..00a4649cbf1 100644 --- a/res/assignSetInfo.py +++ b/res/assignSetInfo.py @@ -120,16 +120,23 @@ if __name__ == '__main__': firstLine = cardfile.readline().strip() cardName = firstLine[5:] + altName = None - print (cardName, fileName) validLines = [] validLines.append(firstLine) for line in cardfile.readlines(): if line[:8] != "SetInfo:" and line[:8] != "SVar:Rar": validLines.append(line.strip()) + if line[:5] == "Name:": + altName = line[5:].strip() cardfile.close() + print (cardName, altName, fileName) + + if not cardName in mtgDataCards and not altName is None: + cardName = altName + for e in mtgDataCards[cardName]: if not setCodeToForge[e] is None: validLines.append( "SetInfo:{} {}".format(setCodeToForge[e], mtgDataCards[cardName][e]) ) diff --git a/res/mtgdata-sets-to-forge.txt b/res/mtgdata-sets-to-forge.txt index 5cc7a6c56ed..a92117a06ae 100644 --- a/res/mtgdata-sets-to-forge.txt +++ b/res/mtgdata-sets-to-forge.txt @@ -25,7 +25,7 @@ AQ ATQ # Antiquities CG UDS # Urza's Destiny CH CHR # Chronicles ===CHK # Champions of Kamigawa ----CM1 # Commander's Arsenal +===CM1 # Commander's Arsenal CMD COM # Magic: The Gathering-Commander CON CFX # Conflux ===CSP # Coldsnap From ba4241e455c84cb8d1b302658095f0df25cd6b18 Mon Sep 17 00:00:00 2001 From: Sloth Date: Mon, 4 Mar 2013 21:18:02 +0000 Subject: [PATCH 04/11] - Battletide Alchemist will no longer ask the player when the AI makes test runs. --- src/main/java/forge/Card.java | 14 +++++++------- src/main/java/forge/GameEntity.java | 2 +- .../forge/card/staticability/StaticAbility.java | 6 +++--- .../staticability/StaticAbilityPreventDamage.java | 4 ++-- .../java/forge/game/ai/ComputerUtilCombat.java | 4 ++-- src/main/java/forge/game/player/Player.java | 6 +++--- 6 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/main/java/forge/Card.java b/src/main/java/forge/Card.java index b279ff9bcbf..c1ff4e33cb9 100644 --- a/src/main/java/forge/Card.java +++ b/src/main/java/forge/Card.java @@ -8002,7 +8002,7 @@ public class Card extends GameEntity implements Comparable { * * @param damage * a int. - * @param possiblePrvenetion + * @param possiblePrevention * a int. * @param source * a {@link forge.Card} object. @@ -8010,7 +8010,7 @@ public class Card extends GameEntity implements Comparable { * a boolean. * @return a int. */ - public final int staticDamagePrevention(final int damage, final int possiblePrvenetion, final Card source, + public final int staticDamagePrevention(final int damage, final int possiblePrevention, final Card source, final boolean isCombat) { if (Singletons.getModel().getGame().getStaticEffects().getGlobalRuleChange(GlobalRuleChange.noPrevention)) { @@ -8047,9 +8047,9 @@ public class Card extends GameEntity implements Comparable { } } - int restDamage = damage - possiblePrvenetion; + int restDamage = damage - possiblePrevention; - restDamage = this.staticDamagePrevention(restDamage, source, isCombat); + restDamage = this.staticDamagePrevention(restDamage, source, isCombat, true); return restDamage; } @@ -8070,7 +8070,7 @@ public class Card extends GameEntity implements Comparable { * @return a int. */ @Override - public final int staticDamagePrevention(final int damageIn, final Card source, final boolean isCombat) { + public final int staticDamagePrevention(final int damageIn, final Card source, final boolean isCombat, final boolean isTest) { if (Singletons.getModel().getGame().getStaticEffects().getGlobalRuleChange(GlobalRuleChange.noPrevention)) { return damageIn; @@ -8138,7 +8138,7 @@ public class Card extends GameEntity implements Comparable { for (final Card ca : Singletons.getModel().getGame().getCardsIn(ZoneType.listValueOf("Battlefield,Command"))) { final ArrayList staticAbilities = ca.getStaticAbilities(); for (final StaticAbility stAb : staticAbilities) { - restDamage = stAb.applyAbility("PreventDamage", source, this, restDamage, isCombat); + restDamage = stAb.applyAbility("PreventDamage", source, this, restDamage, isCombat, isTest); } } @@ -8198,7 +8198,7 @@ public class Card extends GameEntity implements Comparable { return 0; } - restDamage = this.staticDamagePrevention(restDamage, source, isCombat); + restDamage = this.staticDamagePrevention(restDamage, source, isCombat, false); if (restDamage == 0) { return 0; diff --git a/src/main/java/forge/GameEntity.java b/src/main/java/forge/GameEntity.java index 0e54b6167d1..8952b10b9d8 100644 --- a/src/main/java/forge/GameEntity.java +++ b/src/main/java/forge/GameEntity.java @@ -139,7 +139,7 @@ public abstract class GameEntity extends MyObservable { * a boolean. * @return a int. */ - public int staticDamagePrevention(final int damage, final Card source, final boolean isCombat) { + public int staticDamagePrevention(final int damage, final Card source, final boolean isCombat, final boolean isTest) { return 0; } diff --git a/src/main/java/forge/card/staticability/StaticAbility.java b/src/main/java/forge/card/staticability/StaticAbility.java index d92b767eb3d..acf003ee87e 100644 --- a/src/main/java/forge/card/staticability/StaticAbility.java +++ b/src/main/java/forge/card/staticability/StaticAbility.java @@ -253,12 +253,12 @@ public class StaticAbility { * the target * @param in * the in - * @param b + * @param isCombat * the b * @return the int */ public final int applyAbility(final String mode, final Card source, final GameEntity target, final int in, - final boolean b) { + final boolean isCombat, final boolean isTest) { // don't apply the ability if it hasn't got the right mode if (!this.params.get("Mode").equals(mode)) { @@ -270,7 +270,7 @@ public class StaticAbility { } if (mode.equals("PreventDamage")) { - return StaticAbilityPreventDamage.applyPreventDamageAbility(this, source, target, in, b); + return StaticAbilityPreventDamage.applyPreventDamageAbility(this, source, target, in, isCombat, isTest); } return in; diff --git a/src/main/java/forge/card/staticability/StaticAbilityPreventDamage.java b/src/main/java/forge/card/staticability/StaticAbilityPreventDamage.java index 5f59edf407b..02b8545d568 100644 --- a/src/main/java/forge/card/staticability/StaticAbilityPreventDamage.java +++ b/src/main/java/forge/card/staticability/StaticAbilityPreventDamage.java @@ -44,7 +44,7 @@ public class StaticAbilityPreventDamage { * @return the int */ public static int applyPreventDamageAbility(final StaticAbility stAb, final Card source, final GameEntity target, - final int damage, final boolean isCombat) { + final int damage, final boolean isCombat, final boolean isTest) { final HashMap params = stAb.getMapParams(); final Card hostCard = stAb.getHostCard(); int restDamage = damage; @@ -71,7 +71,7 @@ public class StaticAbilityPreventDamage { return restDamage; } - if (params.containsKey("Optional")) { //Assume if param is present it should be optional + if (!isTest && params.containsKey("Optional")) { //Assume if param is present it should be optional final String logic = params.containsKey("AILogic") ? params.get("AILogic") : ""; final String message = "Apply the effect of " + hostCard + "?"; boolean confirmed = hostCard.getController().getController().confirmStaticApplication(hostCard, target, logic, message); diff --git a/src/main/java/forge/game/ai/ComputerUtilCombat.java b/src/main/java/forge/game/ai/ComputerUtilCombat.java index f9ac54c0223..788eec485d1 100644 --- a/src/main/java/forge/game/ai/ComputerUtilCombat.java +++ b/src/main/java/forge/game/ai/ComputerUtilCombat.java @@ -1857,7 +1857,7 @@ public class ComputerUtilCombat { } } - restDamage = target.staticDamagePrevention(restDamage, source, isCombat); + restDamage = target.staticDamagePrevention(restDamage, source, isCombat, true); return restDamage; } @@ -1882,7 +1882,7 @@ public class ComputerUtilCombat { int restDamage = damage; restDamage = target.staticReplaceDamage(restDamage, source, isCombat); - restDamage = target.staticDamagePrevention(restDamage, source, isCombat); + restDamage = target.staticDamagePrevention(restDamage, source, isCombat, true); return restDamage; } diff --git a/src/main/java/forge/game/player/Player.java b/src/main/java/forge/game/player/Player.java index d2d3d7d9688..a8d5cde84fd 100644 --- a/src/main/java/forge/game/player/Player.java +++ b/src/main/java/forge/game/player/Player.java @@ -672,7 +672,7 @@ public abstract class Player extends GameEntity implements Comparable { * @return a int. */ @Override - public final int staticDamagePrevention(final int damage, final Card source, final boolean isCombat) { + public final int staticDamagePrevention(final int damage, final Card source, final boolean isCombat, final boolean isTest) { if (Singletons.getModel().getGame().getStaticEffects().getGlobalRuleChange(GlobalRuleChange.noPrevention)) { return damage; @@ -709,7 +709,7 @@ public abstract class Player extends GameEntity implements Comparable { for (final Card ca : game.getCardsIn(ZoneType.listValueOf("Battlefield,Command"))) { final ArrayList staticAbilities = ca.getStaticAbilities(); for (final StaticAbility stAb : staticAbilities) { - restDamage = stAb.applyAbility("PreventDamage", source, this, restDamage, isCombat); + restDamage = stAb.applyAbility("PreventDamage", source, this, restDamage, isCombat, isTest); } } @@ -884,7 +884,7 @@ public abstract class Player extends GameEntity implements Comparable { return 0; } - restDamage = this.staticDamagePrevention(restDamage, source, isCombat); + restDamage = this.staticDamagePrevention(restDamage, source, isCombat, false); if (restDamage >= this.getPreventNextDamage()) { restDamage = restDamage - this.getPreventNextDamage(); From 7e40feff92382c53bf002d2fc3415d91c49df6b0 Mon Sep 17 00:00:00 2001 From: Sloth Date: Mon, 4 Mar 2013 21:20:51 +0000 Subject: [PATCH 05/11] - Battletide Alchemist will now list the target in the query. --- .../forge/card/staticability/StaticAbilityPreventDamage.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/forge/card/staticability/StaticAbilityPreventDamage.java b/src/main/java/forge/card/staticability/StaticAbilityPreventDamage.java index 02b8545d568..0441c16a1aa 100644 --- a/src/main/java/forge/card/staticability/StaticAbilityPreventDamage.java +++ b/src/main/java/forge/card/staticability/StaticAbilityPreventDamage.java @@ -73,7 +73,7 @@ public class StaticAbilityPreventDamage { if (!isTest && params.containsKey("Optional")) { //Assume if param is present it should be optional final String logic = params.containsKey("AILogic") ? params.get("AILogic") : ""; - final String message = "Apply the effect of " + hostCard + "?"; + final String message = "Apply the effect of " + hostCard + "? (Affected: " + target + ")"; boolean confirmed = hostCard.getController().getController().confirmStaticApplication(hostCard, target, logic, message); if (!confirmed) { From 52f5879435e15b93560031943db021df67939702 Mon Sep 17 00:00:00 2001 From: Sloth Date: Mon, 4 Mar 2013 21:29:19 +0000 Subject: [PATCH 06/11] - playSpellAbilityForFree is not optional - removed the "may". --- src/main/java/forge/card/cardfactory/CardFactory.java | 2 +- src/main/java/forge/game/player/PlayerController.java | 2 +- src/main/java/forge/game/player/PlayerControllerAi.java | 7 ++++--- src/main/java/forge/game/player/PlayerControllerHuman.java | 2 +- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/main/java/forge/card/cardfactory/CardFactory.java b/src/main/java/forge/card/cardfactory/CardFactory.java index 6468bcf71d2..07749d13efb 100644 --- a/src/main/java/forge/card/cardfactory/CardFactory.java +++ b/src/main/java/forge/card/cardfactory/CardFactory.java @@ -224,7 +224,7 @@ public class CardFactory { } } - controller.getController().mayPlaySpellAbilityForFree(copySA); + controller.getController().playSpellAbilityForFree(copySA); //c.addController(originalController); } diff --git a/src/main/java/forge/game/player/PlayerController.java b/src/main/java/forge/game/player/PlayerController.java index ec4e3a61669..60fc5ab4808 100644 --- a/src/main/java/forge/game/player/PlayerController.java +++ b/src/main/java/forge/game/player/PlayerController.java @@ -76,7 +76,7 @@ public abstract class PlayerController { */ public abstract void playFromSuspend(Card c); public abstract boolean playCascade(Card cascadedCard, Card sourceCard); - public abstract void mayPlaySpellAbilityForFree(SpellAbility copySA); + public abstract void playSpellAbilityForFree(SpellAbility copySA); /** * @return the player */ diff --git a/src/main/java/forge/game/player/PlayerControllerAi.java b/src/main/java/forge/game/player/PlayerControllerAi.java index ef9bd250e0b..89b9daaf663 100644 --- a/src/main/java/forge/game/player/PlayerControllerAi.java +++ b/src/main/java/forge/game/player/PlayerControllerAi.java @@ -138,13 +138,14 @@ public class PlayerControllerAi extends PlayerController { * @see forge.game.player.PlayerController#mayPlaySpellAbilityForFree(forge.card.spellability.SpellAbility) */ @Override - public void mayPlaySpellAbilityForFree(SpellAbility copySA) { + public void playSpellAbilityForFree(SpellAbility copySA) { if (copySA instanceof Spell) { Spell spell = (Spell) copySA; - if (spell.canPlayFromEffectAI(false, true)) { + if (spell.canPlayFromEffectAI(true, true)) { ComputerUtil.playStackFree(getPlayer(), copySA); } - } else if (copySA.canPlayAI()) { + } else { + copySA.canPlayAI(); ComputerUtil.playStackFree(getPlayer(), copySA); } } diff --git a/src/main/java/forge/game/player/PlayerControllerHuman.java b/src/main/java/forge/game/player/PlayerControllerHuman.java index cd2787e786e..e749b87b238 100644 --- a/src/main/java/forge/game/player/PlayerControllerHuman.java +++ b/src/main/java/forge/game/player/PlayerControllerHuman.java @@ -113,7 +113,7 @@ public class PlayerControllerHuman extends PlayerController { * @see forge.game.player.PlayerController#mayPlaySpellAbilityForFree(forge.card.spellability.SpellAbility) */ @Override - public void mayPlaySpellAbilityForFree(SpellAbility copySA) { + public void playSpellAbilityForFree(SpellAbility copySA) { game.getActionPlay().playSpellAbilityForFree(copySA); } From 597077cce05bdbf0bcbce12b13ce07e7434cdfc7 Mon Sep 17 00:00:00 2001 From: Sloth Date: Mon, 4 Mar 2013 21:38:53 +0000 Subject: [PATCH 07/11] - Fixed BondEffect. --- src/main/java/forge/card/ability/effects/BondEffect.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/forge/card/ability/effects/BondEffect.java b/src/main/java/forge/card/ability/effects/BondEffect.java index ccd0fbb3476..268d0becc81 100644 --- a/src/main/java/forge/card/ability/effects/BondEffect.java +++ b/src/main/java/forge/card/ability/effects/BondEffect.java @@ -30,7 +30,7 @@ public class BondEffect extends SpellAbilityEffect { Card partner = cards.get(0); // skip choice if only one card on list if (cards.size() > 1) { - sa.getActivatingPlayer().getController().chooseSingleCardForEffect(cards, sa, "Select a card to pair with"); + partner = sa.getActivatingPlayer().getController().chooseSingleCardForEffect(cards, sa, "Select a card to pair with"); } // pair choices together From 906bfaa1b5f131b12e50f521e605c77e2a402476 Mon Sep 17 00:00:00 2001 From: myk Date: Mon, 4 Mar 2013 21:42:03 +0000 Subject: [PATCH 08/11] fix stale hover when alt-tabbing off the app then clicking back on it; also fix NPE when a card disappears from under the cursor --- .../java/forge/view/arcane/CardPanelContainer.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/main/java/forge/view/arcane/CardPanelContainer.java b/src/main/java/forge/view/arcane/CardPanelContainer.java index 340ee24c277..ccadd9d16a4 100644 --- a/src/main/java/forge/view/arcane/CardPanelContainer.java +++ b/src/main/java/forge/view/arcane/CardPanelContainer.java @@ -570,8 +570,17 @@ public abstract class CardPanelContainer extends JPanel { public final Card getHoveredCard(MouseEvent e) { // re-evaluate cursor position so if we hovered over a card, alt-tabbed out of the application, then // clicked back on the application somewhere else, the last hovered card won't register the click + // this cannot protect against alt tabbing off then re-focusing on the application by clicking on + // the already-hovered card, though, since we cannot tell the difference between that and clicking + // on the hovered card when the app already has focus. CardPanel p = getCardPanel(e.getX(), e.getY()); - return (p == null && p == hoveredPanel) ? null : p.getGameCard(); + + // if cursor has jumped, for example via the above alt-tabbing example, fix the card hover highlight + if (null != hoveredPanel && p != hoveredPanel) { + mouseOut(hoveredPanel, e); + } + + return (null == p || p != hoveredPanel) ? null : p.getGameCard(); } /** From c6894de100a0c7702e4f43f792d9955c6065e701 Mon Sep 17 00:00:00 2001 From: Sloth Date: Mon, 4 Mar 2013 22:14:22 +0000 Subject: [PATCH 09/11] - canPlayFromEffectAI will now check for NeedsToPlay SVars. --- src/main/java/forge/card/ability/SpellApiBased.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/forge/card/ability/SpellApiBased.java b/src/main/java/forge/card/ability/SpellApiBased.java index 287e5723036..e52b4cdcdeb 100644 --- a/src/main/java/forge/card/ability/SpellApiBased.java +++ b/src/main/java/forge/card/ability/SpellApiBased.java @@ -60,6 +60,6 @@ public class SpellApiBased extends Spell { chance = ai.doTriggerNoCostWithSubs((AIPlayer)this.getActivatingPlayer(), this, mandatory); } chance = ai.doTriggerAI((AIPlayer)this.getActivatingPlayer(), this, mandatory); - return chance; + return chance && super.canPlayAI(); } } From 25d68acde6fb8fb1bd1e182a70b8685185bc7c9a Mon Sep 17 00:00:00 2001 From: Sloth Date: Mon, 4 Mar 2013 22:16:09 +0000 Subject: [PATCH 10/11] - Added the quest deck Jubilee 2. --- .gitattributes | 1 + res/quest/duels/Jubilee 2.dck | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 res/quest/duels/Jubilee 2.dck diff --git a/.gitattributes b/.gitattributes index 7c90a23f038..6d53625519c 100644 --- a/.gitattributes +++ b/.gitattributes @@ -12986,6 +12986,7 @@ res/quest/duels/Joe[!!-~]Kidd[!!-~]1.dck -text res/quest/duels/Joe[!!-~]Kidd[!!-~]2.dck -text res/quest/duels/Joe[!!-~]Kidd[!!-~]3.dck -text res/quest/duels/Joker[!!-~]2.dck -text +res/quest/duels/Jubilee[!!-~]2.dck -text res/quest/duels/Kane[!!-~]3.dck -text res/quest/duels/Kang[!!-~]1.dck -text res/quest/duels/Kang[!!-~]2.dck -text diff --git a/res/quest/duels/Jubilee 2.dck b/res/quest/duels/Jubilee 2.dck new file mode 100644 index 00000000000..1014c8326b3 --- /dev/null +++ b/res/quest/duels/Jubilee 2.dck @@ -0,0 +1,32 @@ +[duel] +[metadata] +Name=Jubilee 2 +Title=Jubilee +Difficulty=medium +Description=WUBRG multicolored creature Deck with Blessing of the Nephilim and Knight of New Alara +Icon=Jubilee.jpg +Deck Type=constructed +[main] +1 Tropical Island +3 Tundra +3 Savannah +4 Flooded Strand +1 Windswept Heath +2 Vivid Creek +1 Vivid Grove +2 Vivid Meadow +4 Seaside Citadel +2 Reflecting Pool +1 Pillar of the Paruns +4 Blessing of the Nephilim +4 Civic Saber +4 Jaded Response +4 Knight of New Alara +4 Pledge of Loyalty +4 Bant Sureblade +4 Esper Stormblade +1 Fusion Elemental +2 Naya Hushblade +1 Horde of Notions +4 Transguild Courier +[sideboard] From abe0bffdae3006723aef6a1b83ae481985d06834 Mon Sep 17 00:00:00 2001 From: myk Date: Mon, 4 Mar 2013 22:24:12 +0000 Subject: [PATCH 11/11] ensure match message buttons don't steal focus from an overlay at end of game --- src/main/java/forge/gui/SOverlayUtils.java | 7 +++++++ src/main/java/forge/view/ButtonUtil.java | 9 +++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/main/java/forge/gui/SOverlayUtils.java b/src/main/java/forge/gui/SOverlayUtils.java index bff7798df8d..31ca29a0691 100644 --- a/src/main/java/forge/gui/SOverlayUtils.java +++ b/src/main/java/forge/gui/SOverlayUtils.java @@ -119,12 +119,18 @@ public final class SOverlayUtils { return overlay; } + private static boolean _overlayHasFocus; + public static boolean overlayHasFocus() { + return _overlayHasFocus; + } + private static Component prevFocusOwner; public static void showOverlay() { prevFocusOwner = FocusManager.getCurrentKeyboardFocusManager().getPermanentFocusOwner(); FOverlay.SINGLETON_INSTANCE.getPanel().setVisible(true); // ensure no background element has focus FOverlay.SINGLETON_INSTANCE.getPanel().requestFocusInWindow(); + _overlayHasFocus = true; } /** @@ -137,6 +143,7 @@ public final class SOverlayUtils { prevFocusOwner.requestFocusInWindow(); prevFocusOwner = null; } + _overlayHasFocus = false; } public static void showTargetingOverlay() { diff --git a/src/main/java/forge/view/ButtonUtil.java b/src/main/java/forge/view/ButtonUtil.java index a30175a2547..15464b30390 100644 --- a/src/main/java/forge/view/ButtonUtil.java +++ b/src/main/java/forge/view/ButtonUtil.java @@ -19,6 +19,7 @@ package forge.view; import javax.swing.JButton; +import forge.gui.SOverlayUtils; import forge.gui.match.VMatchUI; /** @@ -50,7 +51,7 @@ public class ButtonUtil { getOk().setEnabled(false); getCancel().setEnabled(false); } - + public static void enableAllFocusOk() { enableAndFocus(getOk()); getCancel().setEnabled(true); @@ -58,7 +59,11 @@ public class ButtonUtil { private static void enableAndFocus(final JButton button) { button.setEnabled(true); - button.requestFocusInWindow(); + + // ensure we don't steal focus from an overlay + if (!SOverlayUtils.overlayHasFocus()) { + button.requestFocusInWindow(); + } } private static JButton getOk() {