diff --git a/Mage.Common/src/mage/view/GameView.java b/Mage.Common/src/mage/view/GameView.java index 02adfe140d5..03e9634cce3 100644 --- a/Mage.Common/src/mage/view/GameView.java +++ b/Mage.Common/src/mage/view/GameView.java @@ -95,8 +95,8 @@ public class GameView implements Serializable { } for (StackObject stackObject: state.getStack()) { if (stackObject instanceof StackAbility) { - // Stack Ability - MageObject object = game.getObject(stackObject.getSourceId()); + // Stack Ability + MageObject object = ((StackAbility)stackObject).getSourceObject(game); Card card = game.getCard(stackObject.getSourceId()); if (card != null) { if (object != null) { diff --git a/Mage.Server/src/main/java/mage/server/TableController.java b/Mage.Server/src/main/java/mage/server/TableController.java index e3bcf79632a..d9231e36a16 100644 --- a/Mage.Server/src/main/java/mage/server/TableController.java +++ b/Mage.Server/src/main/java/mage/server/TableController.java @@ -558,7 +558,6 @@ public class TableController { if (!match.getPlayer(entry.getValue()).hasQuit()) { User user = UserManager.getInstance().getUser(entry.getKey()); if (user != null) { - Player player = match.getPlayer(entry.getValue()).getPlayer(); user.ccGameStarted(match.getGame().getId(), entry.getValue()); if (creator == null) { diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/DragonlordsPrerogative.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/DragonlordsPrerogative.java index 1713823c73b..ffb2080d0b1 100644 --- a/Mage.Sets/src/mage/sets/dragonsoftarkir/DragonlordsPrerogative.java +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/DragonlordsPrerogative.java @@ -31,6 +31,7 @@ import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.condition.Condition; +import mage.abilities.costs.Cost; import mage.abilities.costs.common.RevealTargetFromHandCost; import mage.abilities.decorator.ConditionalContinuousRuleModifyingEffect; import mage.abilities.effects.ContinuousRuleModifyingEffect; @@ -114,9 +115,11 @@ class DragonlordsPrerogativeCondition implements Condition { boolean applies = false; Spell spell = game.getStack().getSpell(source.getSourceId()); if (spell != null) { - RevealTargetFromHandCost cost = (RevealTargetFromHandCost) spell.getSpellAbility().getCosts().get(0); - if (cost != null) { - applies = !cost.getTargets().isEmpty(); + for(Cost cost: spell.getSpellAbility().getCosts()) { + if (cost instanceof RevealTargetFromHandCost) { + applies = !((RevealTargetFromHandCost)cost).getTargets().isEmpty(); + break; + } } } if (!applies) { diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/LivingLore.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/LivingLore.java index c16e82de928..9180814c0da 100644 --- a/Mage.Sets/src/mage/sets/dragonsoftarkir/LivingLore.java +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/LivingLore.java @@ -196,9 +196,11 @@ class LivingLoreSacrificeEffect extends OneShotEffect { if (exileId != null) { ExileZone exileZone = game.getExile().getExileZone(exileId); Card exiledCard = null; - for (Card card :exileZone.getCards(game)) { - exiledCard = card; - break; + if (exileZone != null) { + for (Card card :exileZone.getCards(game)) { + exiledCard = card; + break; + } } if (exiledCard != null) { if (exiledCard.getSpellAbility().canChooseTarget(game)) { diff --git a/Mage.Sets/src/mage/sets/mirrodin/AuriokSteelshaper.java b/Mage.Sets/src/mage/sets/mirrodin/AuriokSteelshaper.java index 7bda9b16f13..bc0d94da411 100644 --- a/Mage.Sets/src/mage/sets/mirrodin/AuriokSteelshaper.java +++ b/Mage.Sets/src/mage/sets/mirrodin/AuriokSteelshaper.java @@ -38,7 +38,6 @@ import mage.abilities.effects.common.cost.CostModificationEffectImpl; import mage.abilities.keyword.EquipAbility; import mage.cards.CardImpl; import mage.constants.*; -import mage.filter.FilterAbility; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.SubtypePredicate; diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/BestowTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/BestowTest.java index ff8db21aebc..62bc9f08089 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/BestowTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/BestowTest.java @@ -278,4 +278,34 @@ public class BestowTest extends CardTestPlayerBase { assertPowerToughness(playerA, "Silvercoat Lion", 3,3); } + + /** + * + * + * + */ + @Test + public void bestowMogissWarhound() { + addCard(Zone.BATTLEFIELD, playerA, "Mountain", 3); + // Enchantment Creature — Hound + // 2/2 + // Bestow 2R (If you cast this card for its bestow cost, it's an Aura spell with enchant creature. It becomes a creature again if it's not attached to a creature.) + // Mogis's Warhound attacks each turn if able. + // Enchanted creature gets +2/+2 and attacks each turn if able. + addCard(Zone.HAND, playerA, "Mogis's Warhound"); + addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion"); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Mogis's Warhound using bestow", "Silvercoat Lion"); + + setStopAt(3, PhaseStep.BEGIN_COMBAT); + execute(); + + // + assertHandCount(playerA, "Mogis's Warhound", 0); + + // because cast with bestow, Boon Satyr may not be tapped + assertPermanentCount(playerA, "Silvercoat Lion", 1); + assertPowerToughness(playerA, "Silvercoat Lion", 4,4); + + } } diff --git a/Mage/src/mage/abilities/AbilitiesImpl.java b/Mage/src/mage/abilities/AbilitiesImpl.java index daca919b29a..199a795464d 100644 --- a/Mage/src/mage/abilities/AbilitiesImpl.java +++ b/Mage/src/mage/abilities/AbilitiesImpl.java @@ -31,6 +31,7 @@ package mage.abilities; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; +import java.util.Iterator; import java.util.List; import java.util.UUID; import mage.abilities.common.ZoneChangeTriggeredAbility; @@ -249,7 +250,8 @@ public class AbilitiesImpl extends ArrayList implements Ab @Override public boolean contains(T ability) { - for (T test: this) { + for (Iterator iterator = this.iterator(); iterator.hasNext();) { // simple loop can cause java.util.ConcurrentModificationException + T test = iterator.next(); // Checking also by getRule() without other restrictions is a problem when a triggered ability will be copied to a permanent that had the same ability // already before the copy. Because then it keeps the triggered ability twice and it triggers twice. // e.g. 2 Biovisonary and one enchanted with Infinite Reflection diff --git a/Mage/src/mage/abilities/effects/ContinuousEffectsList.java b/Mage/src/mage/abilities/effects/ContinuousEffectsList.java index 55e1a4e62d9..68b230e3faa 100644 --- a/Mage/src/mage/abilities/effects/ContinuousEffectsList.java +++ b/Mage/src/mage/abilities/effects/ContinuousEffectsList.java @@ -173,7 +173,9 @@ public class ContinuousEffectsList extends ArrayList public void removeEffects(UUID effectIdToRemove, Set abilitiesToRemove) { HashSet abilities = effectAbilityMap.get(effectIdToRemove); - abilities.removeAll(abilitiesToRemove); + if (abilitiesToRemove != null) { + abilities.removeAll(abilitiesToRemove); + } if (abilities.isEmpty()) { for (Iterator iterator = this.iterator(); iterator.hasNext();) { ContinuousEffect effect = iterator.next(); diff --git a/Mage/src/mage/abilities/effects/common/ReturnToBattlefieldUnderYourControlTargetEffect.java b/Mage/src/mage/abilities/effects/common/ReturnToBattlefieldUnderYourControlTargetEffect.java index bcad084f948..89f1b592130 100644 --- a/Mage/src/mage/abilities/effects/common/ReturnToBattlefieldUnderYourControlTargetEffect.java +++ b/Mage/src/mage/abilities/effects/common/ReturnToBattlefieldUnderYourControlTargetEffect.java @@ -29,12 +29,12 @@ package mage.abilities.effects.common; import java.util.UUID; -import mage.MageObject; import mage.constants.Outcome; import mage.constants.Zone; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; import mage.cards.Card; +import mage.game.ExileZone; import mage.game.Game; import mage.players.Player; import mage.util.CardUtil; @@ -79,7 +79,10 @@ public class ReturnToBattlefieldUnderYourControlTargetEffect extends OneShotEffe if (fromExileZone) { UUID exilZoneId = CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter()); if (exilZoneId != null) { - card = game.getExile().getExileZone(exilZoneId).get(getTargetPointer().getFirst(game, source), game); + ExileZone exileZone = game.getExile().getExileZone(exilZoneId); + if (exileZone != null && getTargetPointer().getFirst(game, source) != null) { + card = exileZone.get(getTargetPointer().getFirst(game, source), game); + } } } else { card = game.getCard(targetPointer.getFirst(game, source)); diff --git a/Mage/src/mage/abilities/effects/common/continuous/BoostSourceEffect.java b/Mage/src/mage/abilities/effects/common/continuous/BoostSourceEffect.java index 5abb2c21b48..bb671aa3b69 100644 --- a/Mage/src/mage/abilities/effects/common/continuous/BoostSourceEffect.java +++ b/Mage/src/mage/abilities/effects/common/continuous/BoostSourceEffect.java @@ -39,6 +39,7 @@ import mage.constants.Outcome; import mage.constants.SubLayer; import mage.game.Game; import mage.game.permanent.Permanent; +import org.apache.log4j.Logger; /** * @@ -87,7 +88,11 @@ public class BoostSourceEffect extends ContinuousEffectImpl implements SourceEff public void init(Ability source, Game game) { super.init(source, game); if (affectedObjectsSet) { - affectedObjectList.add(new MageObjectReference(source.getSourceId(), game)); + try { + affectedObjectList.add(new MageObjectReference(source.getSourceId(), game)); + } catch (IllegalArgumentException ex) { + Logger.getLogger(BoostSourceEffect.class).error("Could not get sourceId reference: " + source.getRule()); + } } if (lockedIn) { power = new StaticValue(power.calculate(game, source, this)); diff --git a/Mage/src/mage/players/PlayerImpl.java b/Mage/src/mage/players/PlayerImpl.java index bc4084a77ba..030823510ef 100644 --- a/Mage/src/mage/players/PlayerImpl.java +++ b/Mage/src/mage/players/PlayerImpl.java @@ -709,8 +709,10 @@ public abstract class PlayerImpl implements Player, Serializable { choose(Outcome.Discard, target, source == null ? null : source.getSourceId(), game); for (UUID cardId : target.getTargets()) { Card card = this.getHand().get(cardId, game); - discardedCards.add(card); - discard(card, source, game); + if (card != null) { // can happen if user is removed (session expires) + discardedCards.add(card); + discard(card, source, game); + } } } return discardedCards; diff --git a/Mage/src/mage/util/CardUtil.java b/Mage/src/mage/util/CardUtil.java index 88116bd390e..78cf16a8a16 100644 --- a/Mage/src/mage/util/CardUtil.java +++ b/Mage/src/mage/util/CardUtil.java @@ -208,7 +208,7 @@ public class CardUtil { * @param ability * @param reduceCount */ - public static void adjustAbilityCost(Ability ability, int reduceCount) { + private static void adjustAbilityCost(Ability ability, int reduceCount) { ManaCosts adjustedCost = adjustCost(ability.getManaCostsToPay(), reduceCount); ability.getManaCostsToPay().clear(); ability.getManaCostsToPay().addAll(adjustedCost);