diff --git a/Mage.Server/src/main/java/mage/server/ChatSession.java b/Mage.Server/src/main/java/mage/server/ChatSession.java index 1a3a3914ef..485a37a102 100644 --- a/Mage.Server/src/main/java/mage/server/ChatSession.java +++ b/Mage.Server/src/main/java/mage/server/ChatSession.java @@ -146,7 +146,7 @@ public class ChatSession { if (user.isPresent()) { user.get().fireCallback(clientCallback); } else { - clientsToRemove = new HashSet<>(); + clientsToRemove.add(userId); } } for (UUID userIdToRemove : clientsToRemove) { diff --git a/Mage.Sets/src/mage/cards/a/AnointerPriest.java b/Mage.Sets/src/mage/cards/a/AnointerPriest.java new file mode 100644 index 0000000000..dbcbe3a866 --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/AnointerPriest.java @@ -0,0 +1,78 @@ +/* + * 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.cards.a; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldControlledTriggeredAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.GainLifeEffect; +import mage.abilities.keyword.EmbalmAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.filter.FilterPermanent; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.permanent.TokenPredicate; + +/** + * + * @author LevelX2 + */ +public class AnointerPriest extends CardImpl { + + private static final FilterPermanent filter = new FilterCreaturePermanent("a creature token"); + + static { + filter.add(new TokenPredicate()); + } + + public AnointerPriest(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}"); + + this.subtype.add("Human"); + this.subtype.add("Cleric"); + this.power = new MageInt(1); + this.toughness = new MageInt(3); + + // Whenever a creature token enters the battlefield under your control, you gain 1 life. + this.addAbility(new EntersBattlefieldControlledTriggeredAbility(new GainLifeEffect(1), filter)); + + // Embalm {3}{W} + this.addAbility(new EmbalmAbility(new ManaCostsImpl("{3}{W}"), this)); + } + + public AnointerPriest(final AnointerPriest card) { + super(card); + } + + @Override + public AnointerPriest copy() { + return new AnointerPriest(this); + } +} diff --git a/Mage.Sets/src/mage/cards/c/ConsumingFervor.java b/Mage.Sets/src/mage/cards/c/ConsumingFervor.java index 456f9c468a..4f4dd6dcd6 100644 --- a/Mage.Sets/src/mage/cards/c/ConsumingFervor.java +++ b/Mage.Sets/src/mage/cards/c/ConsumingFervor.java @@ -69,7 +69,7 @@ public class ConsumingFervor extends CardImpl { // Enchanted creature gets +3/+3 and has "At the beginning of your upkeep, put a -1/-1 counter on this creature." ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(3, 3, Duration.WhileOnBattlefield)); - Ability grantedAbility = new BeginningOfUpkeepTriggeredAbility(new AddCountersSourceEffect(CounterType.M1M1.createInstance(1)), TargetController.ANY, false); + Ability grantedAbility = new BeginningOfUpkeepTriggeredAbility(new AddCountersSourceEffect(CounterType.M1M1.createInstance(1)), TargetController.YOU, false); Effect effect = new GainAbilityAttachedEffect(grantedAbility, AttachmentType.AURA); effect.setText("and has \"At the beginning of each upkeep, put a -1/-1 counter on this creature.\""); ability.addEffect(effect); diff --git a/Mage.Sets/src/mage/cards/o/OketrasMonument.java b/Mage.Sets/src/mage/cards/o/OketrasMonument.java index 5d3df615ae..725afe8a48 100644 --- a/Mage.Sets/src/mage/cards/o/OketrasMonument.java +++ b/Mage.Sets/src/mage/cards/o/OketrasMonument.java @@ -69,7 +69,7 @@ public class OketrasMonument extends CardImpl { // White creature spells you cast cost {1} less to cast. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new SpellsCostReductionControllerEffect(filter, 1))); - // Whenever you cast a creature spell, create 1/1 white Warrior creature token with vigilance. + // Whenever you cast a creature spell, create a 1/1 white Warrior creature token with vigilance. this.addAbility(new SpellCastControllerTriggeredAbility(new CreateTokenEffect(new WarriorVigilantToken()), filter2, false)); } diff --git a/Mage.Sets/src/mage/cards/r/RhonassMonument.java b/Mage.Sets/src/mage/cards/r/RhonassMonument.java index ae3ddcfed3..fe8192a901 100644 --- a/Mage.Sets/src/mage/cards/r/RhonassMonument.java +++ b/Mage.Sets/src/mage/cards/r/RhonassMonument.java @@ -32,6 +32,7 @@ import mage.ObjectColor; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.SpellCastControllerTriggeredAbility; +import mage.abilities.effects.Effect; import mage.abilities.effects.common.continuous.BoostTargetEffect; import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; import mage.abilities.effects.common.cost.SpellsCostReductionControllerEffect; @@ -75,7 +76,9 @@ public class RhonassMonument extends CardImpl { // Whenever you cast a creature spell, target creature you control gets +2/+2 and gains trample until end of turn. Ability ability = new SpellCastControllerTriggeredAbility(new BoostTargetEffect(2, 2, Duration.EndOfTurn), filter2, false); - ability.addEffect(new GainAbilityTargetEffect(TrampleAbility.getInstance(), Duration.EndOfTurn)); + Effect effect = new GainAbilityTargetEffect(TrampleAbility.getInstance(), Duration.EndOfTurn); + effect.setText(" and gains trample until end of turn"); + ability.addEffect(effect); ability.addTarget(new TargetCreaturePermanent()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/s/SplendidAgony.java b/Mage.Sets/src/mage/cards/s/SplendidAgony.java index 0071909f00..571b040cb7 100644 --- a/Mage.Sets/src/mage/cards/s/SplendidAgony.java +++ b/Mage.Sets/src/mage/cards/s/SplendidAgony.java @@ -28,8 +28,6 @@ package mage.cards.s; import java.util.UUID; -import mage.abilities.Ability; -import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.effects.common.counter.DistributeCountersEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -47,9 +45,8 @@ public class SplendidAgony extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{B}"); // Distribute two -1/-1 counters among one or two target creatures. - Ability ability = new EntersBattlefieldTriggeredAbility(new DistributeCountersEffect(CounterType.M1M1, 2, false, "one or two target creatures you control"), false); - ability.addTarget(new TargetCreaturePermanentAmount(2)); - this.addAbility(ability); + getSpellAbility().addEffect(new DistributeCountersEffect(CounterType.M1M1, 2, false, "one or two target creatures you control")); + getSpellAbility().addTarget(new TargetCreaturePermanentAmount(2)); } public SplendidAgony(final SplendidAgony card) { diff --git a/Mage/src/main/java/mage/abilities/keyword/EmbalmAbility.java b/Mage/src/main/java/mage/abilities/keyword/EmbalmAbility.java new file mode 100644 index 0000000000..ed87289b54 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/keyword/EmbalmAbility.java @@ -0,0 +1,121 @@ +/* + * 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.keyword; + +import mage.ObjectColor; +import mage.abilities.Ability; +import mage.abilities.ActivatedAbilityImpl; +import mage.abilities.costs.Cost; +import mage.abilities.costs.common.ExileSourceFromGraveCost; +import mage.abilities.effects.OneShotEffect; +import mage.cards.Card; +import mage.constants.Outcome; +import mage.constants.TimingRule; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.permanent.token.EmptyToken; +import mage.players.Player; +import mage.util.CardUtil; + +/** + * + * @author LevelX2 + */ +public class EmbalmAbility extends ActivatedAbilityImpl { + + private String rule; + + public EmbalmAbility(Cost cost, Card card) { + super(Zone.GRAVEYARD, new EmbalmEffect(), cost); + addCost(new ExileSourceFromGraveCost()); + this.rule = setRule(cost, card); + this.timing = TimingRule.SORCERY; + setRule(cost, card); + } + + public EmbalmAbility(final EmbalmAbility ability) { + super(ability); + this.rule = ability.rule; + } + + @Override + public EmbalmAbility copy() { + return new EmbalmAbility(this); + } + + @Override + public String getRule() { + return rule; + } + + private String setRule(Cost cost, Card card) { + StringBuilder sb = new StringBuilder("Embalm ").append(cost.getText()); + sb.append(" (").append(cost.getText()); + sb.append(", Exile this card from your graveyard: Create a token that's a copy of it, except it's a white Zombie "); + for (String subtype : card.getSubtype(null)) { + sb.append(subtype).append(" "); + } + sb.append(" with no mana cost. Embalm only as a sorcery.)"); + return sb.toString(); + } +} + +class EmbalmEffect extends OneShotEffect { + + public EmbalmEffect() { + super(Outcome.PutCreatureInPlay); + } + + public EmbalmEffect(final EmbalmEffect effect) { + super(effect); + } + + @Override + public EmbalmEffect copy() { + return new EmbalmEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Card card = game.getCard(source.getSourceId()); + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null && card != null) { + EmptyToken token = new EmptyToken(); + CardUtil.copyTo(token).from(card); // needed so that entersBattlefied triggered abilities see the attributes (e.g. Master Biomancer) + token.getColor(game).setColor(ObjectColor.WHITE); + if (!token.getSubtype(game).contains("Zombie")) { + token.getSubtype(game).add(0, "Zombie"); + } + token.putOntoBattlefield(1, game, source.getSourceId(), source.getControllerId(), false, false, null); + return true; + } + + return false; + } + +}