From f6dbf0214b3a54de854e8f25e502a55d35e0809d Mon Sep 17 00:00:00 2001
From: LevelX2 <ludwig.hirth@online.de>
Date: Fri, 2 Jan 2015 14:20:12 +0100
Subject: [PATCH] Added ChooseModeEffect  and ModeChoiceSourceCondition.

---
 Mage/src/mage/abilities/AbilityImpl.java      |   3 +-
 .../mage/abilities/TriggeredAbilityImpl.java  |   3 +-
 .../BeginningOfUpkeepTriggeredAbility.java    |  11 ++
 .../common/EntersBattlefieldAbility.java      |   2 +-
 .../common/ZoneChangeAllTriggeredAbility.java |   2 +-
 .../common/ModeChoiceSourceCondition.java     |  52 +++++++++
 .../effects/common/ChooseModeEffect.java      | 106 ++++++++++++++++++
 Utils/release/getting_implemented_cards.txt   |   3 +
 8 files changed, 177 insertions(+), 5 deletions(-)
 create mode 100644 Mage/src/mage/abilities/condition/common/ModeChoiceSourceCondition.java
 create mode 100644 Mage/src/mage/abilities/effects/common/ChooseModeEffect.java

diff --git a/Mage/src/mage/abilities/AbilityImpl.java b/Mage/src/mage/abilities/AbilityImpl.java
index d24400e162..a3b3126d8e 100644
--- a/Mage/src/mage/abilities/AbilityImpl.java
+++ b/Mage/src/mage/abilities/AbilityImpl.java
@@ -212,7 +212,8 @@ public abstract class AbilityImpl implements Ability {
             game.getContinuousEffects().applySpliceEffects(this, game);
         }
 
-        
+        // TODO: Because all (non targeted) choices have to be done during resolution
+        // this has to be removed, if all using effects are changed
         MageObject sourceObject = game.getObject(sourceId);
         if (sourceObject != null) {
             sourceObject.adjustChoices(this, game);
diff --git a/Mage/src/mage/abilities/TriggeredAbilityImpl.java b/Mage/src/mage/abilities/TriggeredAbilityImpl.java
index 2cf4ac746e..92fe31385f 100644
--- a/Mage/src/mage/abilities/TriggeredAbilityImpl.java
+++ b/Mage/src/mage/abilities/TriggeredAbilityImpl.java
@@ -28,6 +28,7 @@
 
 package mage.abilities;
 
+import java.util.UUID;
 import mage.MageObject;
 import mage.abilities.effects.Effect;
 import mage.constants.AbilityType;
@@ -35,8 +36,6 @@ import mage.constants.Zone;
 import mage.game.Game;
 import mage.players.Player;
 
-import java.util.UUID;
-
 /**
  *
  * @author BetaSteward_at_googlemail.com
diff --git a/Mage/src/mage/abilities/common/BeginningOfUpkeepTriggeredAbility.java b/Mage/src/mage/abilities/common/BeginningOfUpkeepTriggeredAbility.java
index c96875afb2..8f1da6641f 100644
--- a/Mage/src/mage/abilities/common/BeginningOfUpkeepTriggeredAbility.java
+++ b/Mage/src/mage/abilities/common/BeginningOfUpkeepTriggeredAbility.java
@@ -43,8 +43,10 @@ import mage.target.targetpointer.FixedTarget;
  */
 
 public class BeginningOfUpkeepTriggeredAbility extends TriggeredAbilityImpl {
+
     private TargetController targetController;
     private boolean setTargetPointer;
+    protected String ruleTrigger;
 
     public BeginningOfUpkeepTriggeredAbility(Effect effect, TargetController targetController, boolean isOptional) {
         this(Zone.BATTLEFIELD, effect, targetController, isOptional);
@@ -55,15 +57,21 @@ public class BeginningOfUpkeepTriggeredAbility extends TriggeredAbilityImpl {
     }
 
     public BeginningOfUpkeepTriggeredAbility(Zone zone, Effect effect, TargetController targetController, boolean isOptional, boolean setTargetPointer) {
+        this(zone, effect, targetController, isOptional, setTargetPointer, null);
+    }
+
+    public BeginningOfUpkeepTriggeredAbility(Zone zone, Effect effect, TargetController targetController, boolean isOptional, boolean setTargetPointer, String ruleTrigger) {
         super(zone, effect, isOptional);
         this.targetController = targetController;
         this.setTargetPointer = setTargetPointer;
+        this.ruleTrigger = ruleTrigger;
     }
 
     public BeginningOfUpkeepTriggeredAbility(final BeginningOfUpkeepTriggeredAbility ability) {
         super(ability);
         this.targetController = ability.targetController;
         this.setTargetPointer = ability.setTargetPointer;
+        this.ruleTrigger = ability.ruleTrigger;
     }
 
     @Override
@@ -126,6 +134,9 @@ public class BeginningOfUpkeepTriggeredAbility extends TriggeredAbilityImpl {
     @Override
     public String getRule() {
         StringBuilder sb = new StringBuilder(super.getRule());
+        if (ruleTrigger != null && !ruleTrigger.isEmpty()) {
+            return sb.insert(0, ruleTrigger).toString();
+        }
         switch (targetController) {
             case YOU:
                 if (this.optional) {
diff --git a/Mage/src/mage/abilities/common/EntersBattlefieldAbility.java b/Mage/src/mage/abilities/common/EntersBattlefieldAbility.java
index 41552c8b36..fa51f39054 100644
--- a/Mage/src/mage/abilities/common/EntersBattlefieldAbility.java
+++ b/Mage/src/mage/abilities/common/EntersBattlefieldAbility.java
@@ -71,7 +71,7 @@ public class EntersBattlefieldAbility extends StaticAbility {
         this.abilityRule = abilityRule;
     }
 
-    public EntersBattlefieldAbility(EntersBattlefieldAbility ability) {
+    public EntersBattlefieldAbility(final EntersBattlefieldAbility ability) {
         super(ability);
         this.abilityRule = ability.abilityRule;
     }
diff --git a/Mage/src/mage/abilities/common/ZoneChangeAllTriggeredAbility.java b/Mage/src/mage/abilities/common/ZoneChangeAllTriggeredAbility.java
index 2615f5e642..6617218192 100644
--- a/Mage/src/mage/abilities/common/ZoneChangeAllTriggeredAbility.java
+++ b/Mage/src/mage/abilities/common/ZoneChangeAllTriggeredAbility.java
@@ -62,7 +62,7 @@ public class ZoneChangeAllTriggeredAbility extends TriggeredAbilityImpl {
         this.filter = filter;
     }
 
-    public ZoneChangeAllTriggeredAbility(ZoneChangeAllTriggeredAbility ability) {
+    public ZoneChangeAllTriggeredAbility(final ZoneChangeAllTriggeredAbility ability) {
         super(ability);
         this.fromZone = ability.fromZone;
         this.toZone = ability.toZone;
diff --git a/Mage/src/mage/abilities/condition/common/ModeChoiceSourceCondition.java b/Mage/src/mage/abilities/condition/common/ModeChoiceSourceCondition.java
new file mode 100644
index 0000000000..aa6defc6f4
--- /dev/null
+++ b/Mage/src/mage/abilities/condition/common/ModeChoiceSourceCondition.java
@@ -0,0 +1,52 @@
+/*
+ *  Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without modification, are
+ *  permitted provided that the following conditions are met:
+ *
+ *     1. Redistributions of source code must retain the above copyright notice, this list of
+ *        conditions and the following disclaimer.
+ *
+ *     2. Redistributions in binary form must reproduce the above copyright notice, this list
+ *        of conditions and the following disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ *  FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
+ *  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ *  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ *  ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  The views and conclusions contained in the software and documentation are those of the
+ *  authors and should not be interpreted as representing official policies, either expressed
+ *  or implied, of BetaSteward_at_googlemail.com.
+ */
+package mage.abilities.condition.common;
+
+import mage.abilities.Ability;
+import mage.abilities.condition.Condition;
+import mage.game.Game;
+
+/**
+ *
+ * @author LevelX2
+ */
+public class ModeChoiceSourceCondition implements Condition {
+
+    private final String mode;
+
+
+    public ModeChoiceSourceCondition(String mode) {
+        this.mode = mode;
+    }
+
+    @Override
+    public boolean apply(Game game, Ability source) {
+        String choosenMode = (String) game.getState().getValue(source.getSourceId() + "_modeChoice");
+        return choosenMode != null && choosenMode.equals(mode);
+    }
+}
diff --git a/Mage/src/mage/abilities/effects/common/ChooseModeEffect.java b/Mage/src/mage/abilities/effects/common/ChooseModeEffect.java
new file mode 100644
index 0000000000..6b8fb7f930
--- /dev/null
+++ b/Mage/src/mage/abilities/effects/common/ChooseModeEffect.java
@@ -0,0 +1,106 @@
+/*
+ *  Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without modification, are
+ *  permitted provided that the following conditions are met:
+ *
+ *     1. Redistributions of source code must retain the above copyright notice, this list of
+ *        conditions and the following disclaimer.
+ *
+ *     2. Redistributions in binary form must reproduce the above copyright notice, this list
+ *        of conditions and the following disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ *  FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
+ *  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ *  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ *  ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  The views and conclusions contained in the software and documentation are those of the
+ *  authors and should not be interpreted as representing official policies, either expressed
+ *  or implied, of BetaSteward_at_googlemail.com.
+ */
+package mage.abilities.effects.common;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import mage.abilities.Ability;
+import mage.abilities.effects.OneShotEffect;
+import mage.choices.Choice;
+import mage.choices.ChoiceImpl;
+import mage.constants.Outcome;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.players.Player;
+
+/**
+ *
+ * @author LevelX2
+ */
+public class ChooseModeEffect extends OneShotEffect {
+
+    protected final ArrayList<String> modes = new ArrayList();
+    protected final String choiceMessage;
+
+    public ChooseModeEffect(String choiceMessage, String... modes) {
+        super(Outcome.Neutral);
+        this.choiceMessage = choiceMessage;
+        this.modes.addAll(Arrays.asList(modes));
+        this.staticText = setText();
+    }
+
+    public ChooseModeEffect(final ChooseModeEffect effect) {
+        super(effect);
+        this.modes.addAll(effect.modes);
+        this.choiceMessage = effect.choiceMessage;
+    }
+
+    @Override
+    public ChooseModeEffect copy() {
+        return new ChooseModeEffect(this);
+    }
+
+    @Override
+    public boolean apply(Game game, Ability source) {
+        Player controller = game.getPlayer(source.getControllerId());
+        Permanent sourcePermanent = game.getPermanent(source.getSourceId());
+        if (controller != null) {
+            Choice choice = new ChoiceImpl(true);
+            choice.setMessage(choiceMessage);
+            choice.getChoices().addAll(modes);
+            while (!choice.isChosen()) {
+                if (!controller.isInGame()) {
+                    return false;
+                }
+                controller.choose(Outcome.Neutral, choice, game);
+            }
+            if (choice.isChosen()) {
+                game.informPlayers(new StringBuilder(sourcePermanent.getLogName()).append(": ").append(controller.getName()).append(" has chosen ").append(choice.getChoice()).toString());
+                game.getState().setValue(source.getSourceId() + "_modeChoice", choice.getChoice());
+                sourcePermanent.addInfo("_modeChoice", "<font color = 'blue'>Chosen mode: " + choice.getChoice() + "</font>");
+            }
+            return true;
+        }
+        return false;
+    }
+
+    private String setText() {
+        StringBuilder sb = new StringBuilder("choose ");
+        int count = 0;
+        for (String choice: modes) {
+            count++;
+            sb.append(choice);
+            if (count + 1 < modes.size()) {
+                sb.append(", ");
+            } else if (count < modes.size()) {
+                sb.append(" or ");
+            }
+        }
+        return sb.toString();
+    }
+}
diff --git a/Utils/release/getting_implemented_cards.txt b/Utils/release/getting_implemented_cards.txt
index 6ba18b676c..455cfbeddc 100644
--- a/Utils/release/getting_implemented_cards.txt
+++ b/Utils/release/getting_implemented_cards.txt
@@ -81,6 +81,9 @@ git log 96ce77e9d0e21610569071c81e661f91c53a3a17..HEAD --diff-filter=A --name-st
 since 1.3.0-2014-11-29v5 (2014-12-27)
 git log c4ad51c4af2467f3483204e29f23b76c53f8f880..HEAD --diff-filter=A --name-status | sed -ne "s/^A[^u]Mage.Sets\/src\/mage\/sets\///p" | sort > added_cards.txt
 
+since 1.3.0-2014-11-29v7 (2015-01-01)
+git log c370189787cff7fc129b1ccf1b223807143460de..HEAD --diff-filter=A --name-status | sed -ne "s/^A[^u]Mage.Sets\/src\/mage\/sets\///p" | sort > added_cards.txt
+
 3. Copy added_cards.txt to trunk\Utils folder
 4. Run script:
 > perl extract_in_wiki_format.perl