diff --git a/Mage.Server/src/main/java/mage/server/game/GameController.java b/Mage.Server/src/main/java/mage/server/game/GameController.java index 0046d625c07..1787d6739ed 100644 --- a/Mage.Server/src/main/java/mage/server/game/GameController.java +++ b/Mage.Server/src/main/java/mage/server/game/GameController.java @@ -27,6 +27,11 @@ */ package mage.server.game; +import java.io.*; +import java.util.*; +import java.util.Map.Entry; +import java.util.concurrent.*; +import java.util.zip.GZIPOutputStream; import mage.MageException; import mage.abilities.Ability; import mage.cards.Card; @@ -61,12 +66,6 @@ import mage.view.ChatMessage.MessageColor; import mage.view.ChatMessage.MessageType; import org.apache.log4j.Logger; -import java.io.*; -import java.util.*; -import java.util.Map.Entry; -import java.util.concurrent.*; -import java.util.zip.GZIPOutputStream; - /** * @author BetaSteward_at_googlemail.com */ @@ -271,8 +270,8 @@ public class GameController implements GameCallback { }; PriorityTimer timer = new PriorityTimer(count, delayMs, executeOnNoTimeLeft); - timers.put(playerId, timer); timer.init(game.getId()); + timers.put(playerId, timer); return timer; } @@ -983,6 +982,7 @@ public class GameController implements GameCallback { @FunctionalInterface interface Command { + void execute(UUID player); } diff --git a/Mage.Sets/src/mage/cards/a/AthreosGodOfPassage.java b/Mage.Sets/src/mage/cards/a/AthreosGodOfPassage.java index 093b7ff0df8..3e888169ba4 100644 --- a/Mage.Sets/src/mage/cards/a/AthreosGodOfPassage.java +++ b/Mage.Sets/src/mage/cards/a/AthreosGodOfPassage.java @@ -39,6 +39,7 @@ import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.continuous.LoseCreatureTypeSourceEffect; import mage.abilities.keyword.IndestructibleAbility; +import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.*; @@ -49,7 +50,6 @@ import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; import mage.game.events.ZoneChangeEvent; -import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.common.TargetOpponent; @@ -67,7 +67,7 @@ public class AthreosGodOfPassage extends CardImpl { } public AthreosGodOfPassage(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT,CardType.CREATURE},"{1}{W}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, "{1}{W}{B}"); addSuperType(SuperType.LEGENDARY); this.subtype.add(SubType.GOD); @@ -118,7 +118,7 @@ class AthreosGodOfPassageReturnEffect extends OneShotEffect { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { UUID creatureId = (UUID) this.getValue("creatureId"); - Permanent creature = game.getPermanentOrLKIBattlefield(creatureId); + Card creature = game.getCard(creatureId); if (creature != null) { Player opponent = game.getPlayer(source.getFirstTarget()); boolean paid = false; @@ -133,7 +133,7 @@ class AthreosGodOfPassageReturnEffect extends OneShotEffect { } if (opponent == null || !paid) { if (game.getState().getZone(creature.getId()) == Zone.GRAVEYARD) { - controller.moveCards(game.getCard(creatureId), Zone.HAND, source, game); + controller.moveCards(creature, Zone.HAND, source, game); } } } @@ -171,8 +171,7 @@ class AthreosDiesCreatureTriggeredAbility extends TriggeredAbilityImpl { public boolean checkTrigger(GameEvent event, Game game) { ZoneChangeEvent zEvent = (ZoneChangeEvent) event; if (zEvent.getFromZone() == Zone.BATTLEFIELD && zEvent.getToZone() == Zone.GRAVEYARD) { - Permanent permanent = (Permanent) game.getLastKnownInformation(event.getTargetId(), Zone.BATTLEFIELD); - if (permanent != null && filter.match(permanent, sourceId, controllerId, game)) { + if (zEvent.getTarget() != null && filter.match(zEvent.getTarget(), sourceId, controllerId, game)) { for (Effect effect : this.getEffects()) { effect.setValue("creatureId", event.getTargetId()); } diff --git a/Mage.Sets/src/mage/cards/b/BlazingTorch.java b/Mage.Sets/src/mage/cards/b/BlazingTorch.java index 83239ba3522..805ccc9972b 100644 --- a/Mage.Sets/src/mage/cards/b/BlazingTorch.java +++ b/Mage.Sets/src/mage/cards/b/BlazingTorch.java @@ -55,7 +55,7 @@ import mage.target.common.TargetCreatureOrPlayer; public class BlazingTorch extends CardImpl { public BlazingTorch(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{1}"); + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{1}"); this.subtype.add("Equipment"); // Equipped creature can't be blocked by Vampires or Zombies. (!this is a static ability of the equipment) @@ -95,7 +95,7 @@ class BlazingTorchEvasionEffect extends RestrictionEffect { Permanent equipment = game.getPermanent(source.getSourceId()); if (equipment != null && equipment.getAttachedTo() != null) { Permanent equipped = game.getPermanent(equipment.getAttachedTo()); - if (permanent.getId().equals(equipped.getId())) { + if (equipped != null && permanent.getId().equals(equipped.getId())) { return true; } } diff --git a/Mage.Sets/src/mage/cards/c/CarrionThrash.java b/Mage.Sets/src/mage/cards/c/CarrionThrash.java index ccd450b0a4e..c2b6d9f23bd 100644 --- a/Mage.Sets/src/mage/cards/c/CarrionThrash.java +++ b/Mage.Sets/src/mage/cards/c/CarrionThrash.java @@ -37,7 +37,7 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.filter.common.FilterCreatureCard; -import mage.filter.predicate.permanent.AnotherPredicate; +import mage.filter.predicate.mageobject.AnotherCardPredicate; import mage.target.common.TargetCardInYourGraveyard; /** @@ -47,12 +47,13 @@ import mage.target.common.TargetCardInYourGraveyard; public class CarrionThrash extends CardImpl { private static final FilterCreatureCard filter = new FilterCreatureCard("another creature card from your graveyard"); + static { - filter.add(new AnotherPredicate()); + filter.add(new AnotherCardPredicate()); } public CarrionThrash(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{B}{R}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}{R}{G}"); this.subtype.add("Viashino"); this.subtype.add("Warrior"); diff --git a/Mage.Sets/src/mage/cards/c/ChandraTorchOfDefiance.java b/Mage.Sets/src/mage/cards/c/ChandraTorchOfDefiance.java index 0ca23c7cbaa..2d4f9cac48d 100644 --- a/Mage.Sets/src/mage/cards/c/ChandraTorchOfDefiance.java +++ b/Mage.Sets/src/mage/cards/c/ChandraTorchOfDefiance.java @@ -93,7 +93,7 @@ class ChandraTorchOfDefianceEffect extends OneShotEffect { public ChandraTorchOfDefianceEffect() { super(Outcome.Detriment); - this.staticText = "Exile the top card of your library. You may cast that card. If you don't, Chandra, Torch of Defiance deals 2 damage to each opponent"; + this.staticText = "Exile the top card of your library. You may cast that card. If you don't, {this} deals 2 damage to each opponent"; } public ChandraTorchOfDefianceEffect(final ChandraTorchOfDefianceEffect effect) { @@ -111,17 +111,12 @@ class ChandraTorchOfDefianceEffect extends OneShotEffect { MageObject sourceObject = source.getSourceObject(game); if (controller != null && sourceObject != null && controller.getLibrary().hasCards()) { Library library = controller.getLibrary(); - Card card = library.removeFromTop(game); + Card card = library.getFromTop(game); if (card != null) { boolean exiledCardWasCast = false; controller.moveCardToExileWithInfo(card, source.getSourceId(), sourceObject.getIdName(), source.getSourceId(), game, Zone.LIBRARY, true); if (!card.getManaCost().isEmpty()) { if (controller.chooseUse(Outcome.Benefit, "Cast the card? (You still pay the costs)", source, game) && !card.isLand()) { -// LinkedHashMap useableAbilities = controller.getUseableActivatedAbilities(card, Zone.EXILED, game); -// for (ActivatedAbility ability : useableAbilities.values()) { -// -// } -// controller.activateAbility(useableAbilities, game); exiledCardWasCast = controller.cast(card.getSpellAbility(), game, false); } } diff --git a/Mage.Sets/src/mage/cards/w/WildfireEternal.java b/Mage.Sets/src/mage/cards/w/WildfireEternal.java index c5c911cc50e..ed524222e2e 100644 --- a/Mage.Sets/src/mage/cards/w/WildfireEternal.java +++ b/Mage.Sets/src/mage/cards/w/WildfireEternal.java @@ -81,7 +81,7 @@ class WildfireEternalCastEffect extends OneShotEffect { public WildfireEternalCastEffect() { super(Outcome.Benefit); - this.staticText = " you may cast an instant or sorcery card from your hand without paying its mana cost."; + this.staticText = "you may cast an instant or sorcery card from your hand without paying its mana cost"; } public WildfireEternalCastEffect(final WildfireEternalCastEffect effect) { diff --git a/Mage/src/main/java/mage/abilities/ActivatedAbilityImpl.java b/Mage/src/main/java/mage/abilities/ActivatedAbilityImpl.java index c37b815e743..5021a83896f 100644 --- a/Mage/src/main/java/mage/abilities/ActivatedAbilityImpl.java +++ b/Mage/src/main/java/mage/abilities/ActivatedAbilityImpl.java @@ -28,6 +28,7 @@ package mage.abilities; import java.util.UUID; +import mage.MageObject; import mage.abilities.costs.Cost; import mage.abilities.costs.Costs; import mage.abilities.costs.mana.ManaCosts; @@ -42,6 +43,7 @@ import mage.constants.TargetController; import mage.constants.TimingRule; import mage.constants.Zone; import mage.game.Game; +import mage.game.command.Emblem; import mage.game.permanent.Permanent; /** @@ -215,9 +217,13 @@ public abstract class ActivatedAbilityImpl extends AbilityImpl implements Activa if (this.controllerId != null && this.controllerId.equals(playerId)) { return true; } else { - Card card = (Card) game.getObject(this.sourceId); - if (card != null && game.getState().getZone(this.sourceId) != Zone.BATTLEFIELD) { - return card.getOwnerId().equals(playerId); + MageObject mageObject = game.getObject(this.sourceId); + if (mageObject instanceof Emblem) { + return ((Emblem) mageObject).getControllerId().equals(playerId); + } else { + if (game.getState().getZone(this.sourceId) != Zone.BATTLEFIELD) { + return ((Card) mageObject).getOwnerId().equals(playerId); + } } } return false; diff --git a/Mage/src/main/java/mage/abilities/effects/common/CounterTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/CounterTargetEffect.java index c569241ae63..f3e1ee52b11 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/CounterTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/CounterTargetEffect.java @@ -69,6 +69,6 @@ public class CounterTargetEffect extends OneShotEffect { if (staticText != null && !staticText.isEmpty()) { return staticText; } - return "counter target " + (mode.getTargets().get(0) != null ? mode.getTargets().get(0).getTargetName() : "spell"); + return "counter target " + (!mode.getTargets().isEmpty() ? mode.getTargets().get(0).getTargetName() : "spell"); } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesColorSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesColorSourceEffect.java index 2ab725e74a2..b7ba3d680c1 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesColorSourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesColorSourceEffect.java @@ -109,9 +109,8 @@ public class BecomesColorSourceEffect extends ContinuousEffectImpl { this.discard(); } return true; - } else { - throw new UnsupportedOperationException("No color set"); } + return false; } @Override diff --git a/Mage/src/main/java/mage/game/combat/CombatGroup.java b/Mage/src/main/java/mage/game/combat/CombatGroup.java index 455f7fb6082..f0ecf761ea0 100644 --- a/Mage/src/main/java/mage/game/combat/CombatGroup.java +++ b/Mage/src/main/java/mage/game/combat/CombatGroup.java @@ -282,20 +282,22 @@ public class CombatGroup implements Serializable, Copyable { if (blocked) { for (UUID blockerId : blockerOrder) { Permanent blocker = game.getPermanent(blockerId); - int lethalDamage; - if (attacker.getAbilities().containsKey(DeathtouchAbility.getInstance().getId())) { - lethalDamage = 1; - } else { - lethalDamage = blocker.getToughness().getValue() - blocker.getDamage(); + if (blocker != null) { + int lethalDamage; + if (attacker.getAbilities().containsKey(DeathtouchAbility.getInstance().getId())) { + lethalDamage = 1; + } else { + lethalDamage = blocker.getToughness().getValue() - blocker.getDamage(); + } + if (lethalDamage >= damage) { + assigned.put(blockerId, damage); + damage = 0; + break; + } + int damageAssigned = player.getAmount(lethalDamage, damage, "Assign damage to " + blocker.getName(), game); + assigned.put(blockerId, damageAssigned); + damage -= damageAssigned; } - if (lethalDamage >= damage) { - assigned.put(blockerId, damage); - damage = 0; - break; - } - int damageAssigned = player.getAmount(lethalDamage, damage, "Assign damage to " + blocker.getName(), game); - assigned.put(blockerId, damageAssigned); - damage -= damageAssigned; } if (damage > 0 && hasTrample(attacker)) { defenderDamage(attacker, damage, game);