It is currently 07 Sep 2025, 15:30
   
Text Size

New set Dragons of Tarkir

Moderators: North, BetaSteward, noxx, jeffwadsworth, JayDi, TheElk801, LevelX, CCGHQ Admins

Re: New set Dragons of Tarkir

Postby fireshoes » 10 Mar 2015, 04:25

jeffwadsworth wrote:You will need something like TargetCreatureOrPlaneswalkerAmount(). Try this code.

Code: Select all
/*
 * 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.target.common;

import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import mage.constants.Zone;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.dynamicvalue.common.StaticValue;
import mage.filter.Filter;
import mage.filter.common.FilterCreatureOrPlaneswalkerPermanent;
import mage.filter.common.FilterCreaturePermanent;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.target.TargetAmount;

/**
 *
 * @author BetaSteward_at_googlemail.com
 */
public class TargetCreatureOrPlaneswalkerAmount extends TargetAmount {

    protected FilterCreatureOrPlaneswalkerPermanent filter;

    public TargetCreatureOrPlaneswalkerAmount(int amount) {
        // 107.1c If a rule or ability instructs a player to choose “any number,” that player may choose
        // any positive number or zero, unless something (such as damage or counters) is being divided
        // or distributed among “any number” of players and/or objects. In that case, a nonzero number
        // of players and/or objects must be chosen if possible.
        this(new StaticValue(amount));
        this.minNumberOfTargets = 1;
    }

    public TargetCreatureOrPlaneswalkerAmount(DynamicValue amount) {
        super(amount);
        this.zone = Zone.ALL;
        this.filter = new FilterCreatureOrPlaneswalkerPermanent();
        this.targetName = filter.getMessage();
    }

    public TargetCreatureOrPlaneswalkerAmount(final TargetCreatureOrPlaneswalkerAmount target) {
        super(target);
        this.filter = target.filter.copy();
    }

    @Override
    public Filter getFilter() {
        return this.filter;
    }

    @Override
    public boolean canTarget(UUID id, Game game) {
        Permanent permanent = game.getPermanent(id);
        if (permanent != null) {
            return filter.match(permanent, game);
        }
        return false;
    }

    @Override
    public boolean canTarget(UUID id, Ability source, Game game) {
        Permanent permanent = game.getPermanent(id);
        if (source != null) {
            MageObject targetSource = game.getObject(source.getSourceId());
            if (permanent != null) {
                return permanent.canBeTargetedBy(targetSource, source.getControllerId(), game) && filter.match(permanent, source.getSourceId(), source.getControllerId(), game);
            }
        }

        if (permanent != null) {
            return filter.match(permanent, game);
        }
        return false;
    }

    @Override
    public boolean canTarget(UUID playerId, UUID id, Ability source, Game game) {
        return canTarget(id, source, game);
    }

    @Override
    public boolean canChoose(UUID sourceId, UUID sourceControllerId, Game game) {
        int count = 0;
        MageObject targetSource = game.getObject(sourceId);
        for (Permanent permanent : game.getBattlefield().getActivePermanents(new FilterCreaturePermanent(), sourceControllerId, game)) {
            if (permanent.canBeTargetedBy(targetSource, sourceControllerId, game) && filter.match(permanent, sourceId, sourceControllerId, game)) {
                count++;
                if (count >= this.minNumberOfTargets) {
                    return true;
                }
            }
        }
        return false;
    }

    @Override
    public boolean canChoose(UUID sourceControllerId, Game game) {
        int count = 0;
        for (Permanent permanent : game.getBattlefield().getActivePermanents(new FilterCreaturePermanent(), sourceControllerId, game)) {
            if (filter.match(permanent, null, sourceControllerId, game)) {
                count++;
                if (count >= this.minNumberOfTargets) {
                    return true;
                }
            }
        }
        return false;
    }

    @Override
    public Set<UUID> possibleTargets(UUID sourceId, UUID sourceControllerId, Game game) {
        Set<UUID> possibleTargets = new HashSet<>();
        MageObject targetSource = game.getObject(sourceId);
        for (Permanent permanent : game.getBattlefield().getActivePermanents(new FilterCreaturePermanent(), sourceControllerId, game)) {
            if (permanent.canBeTargetedBy(targetSource, sourceControllerId, game) && filter.match(permanent, sourceId, sourceControllerId, game)) {
                possibleTargets.add(permanent.getId());
            }
        }
        return possibleTargets;
    }

    @Override
    public Set<UUID> possibleTargets(UUID sourceControllerId, Game game) {
        Set<UUID> possibleTargets = new HashSet<>();
        for (Permanent permanent : game.getBattlefield().getActivePermanents(new FilterCreaturePermanent(), sourceControllerId, game)) {
            if (filter.match(permanent, null, sourceControllerId, game)) {
                possibleTargets.add(permanent.getId());
            }
        }
        return possibleTargets;
    }

    @Override
    public String getTargetedName(Game game) {
        StringBuilder sb = new StringBuilder();
        for (UUID targetId : getTargets()) {
            Permanent permanent = game.getPermanent(targetId);
            if (permanent != null) {
                sb.append(permanent.getLogName()).append("(").append(getTargetAmount(targetId)).append(") ");
            }
        }
        return sb.toString();
    }

    @Override
    public TargetCreatureOrPlaneswalkerAmount copy() {
        return new TargetCreatureOrPlaneswalkerAmount(this);
    }

}
This worked good, except am I able to filter it to target only creatures and planeswalkers my opponents control?
User avatar
fireshoes
 
Posts: 536
Joined: 20 Aug 2014, 03:51
Has thanked: 201 times
Been thanked: 49 times

Re: New set Dragons of Tarkir

Postby jeffwadsworth » 10 Mar 2015, 16:17

fireshoes wrote:Having a problem with Display of Dominance's Permanents you control can't be the targets of blue of black spells your opponents control this turn. section. Got an Null Pointer Exception as Computer's Terminate was resolving after my Display of Dominance had resolved.
Code: Select all
java.lang.NullPointerException
   at mage.filter.predicate.permanent.ControllerPredicate.apply(ControllerPredicate.java:63)
   at mage.filter.predicate.permanent.ControllerPredicate.apply(ControllerPredicate.java:42)
   at mage.filter.predicate.Predicates$AndPredicate.apply(Predicates.java:172)
   at mage.filter.FilterStackObject.match(FilterStackObject.java:67)
   at mage.filter.FilterSpell.match(FilterSpell.java:59)
   at mage.abilities.effects.common.CantBeTargetedAllEffect.applies(CantBeTargetedAllEffect.java:98)
   at mage.abilities.effects.ContinuousEffects.preventedByRuleModification(ContinuousEffects.java:665)
   at mage.game.GameState.replaceEvent(GameState.java:531)
   at mage.game.GameImpl.replaceEvent(GameImpl.java:2069)
   at mage.target.TargetImpl.isLegal(TargetImpl.java:339)
   at mage.target.Targets.stillLegal(Targets.java:113)
   at mage.game.stack.Spell.spellAbilityHasLegalParts(Spell.java:296)
   at mage.game.stack.Spell.resolve(Spell.java:189)
   at mage.game.GameImpl.resolve(GameImpl.java:1195)
   at mage.game.GameImpl.playPriority(GameImpl.java:1157)
   at mage.game.turn.Step.priority(Step.java:87)
   at mage.game.turn.Phase.playStep(Phase.java:203)
   at mage.game.turn.Phase.play(Phase.java:115)
   at mage.game.turn.Turn.play(Turn.java:140)
   at mage.game.GameImpl.playTurn(GameImpl.java:734)
   at mage.game.GameImpl.play(GameImpl.java:659)
   at mage.game.GameImpl.start(GameImpl.java:626)
   at mage.game.GameImpl.start(GameImpl.java:611)
   at mage.server.game.GameWorker.call(GameWorker.java:60)
   at java.util.concurrent.FutureTask.run(FutureTask.java:262)
   at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
   at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
   at java.lang.Thread.run(Thread.java:745)
Code: Select all
public class DisplayOfDominance extends CardImpl {
   
    private static final FilterPermanent filter = new FilterPermanent("blue or black noncreature permanent");
    private static final FilterSpell filterSource = new FilterSpell("blue or black spells your opponents control");

    static {
        filter.add(Predicates.or(
                new ColorPredicate(ObjectColor.BLACK),
                new ColorPredicate(ObjectColor.BLUE)));
        filter.add(Predicates.not(new CardTypePredicate(CardType.CREATURE)));
        filterSource.add(Predicates.or(
                new ColorPredicate(ObjectColor.BLUE),
                new ColorPredicate(ObjectColor.BLACK)));
        filterSource.add(new ControllerPredicate(TargetController.OPPONENT));
    }

    public DisplayOfDominance(UUID ownerId) {
        super(ownerId, 182, "Display of Dominance", Rarity.UNCOMMON, new CardType[]{CardType.INSTANT}, "{1}{G}");
        this.expansionSetCode = "DTK";

        // Choose one -
        this.getSpellAbility().getModes().setMinModes(1);
        this.getSpellAbility().getModes().setMaxModes(1);
       
        // Destroy target blue or black noncreature permanent;
        this.getSpellAbility().addTarget(new TargetPermanent(filter));
        this.getSpellAbility().addEffect(new DestroyTargetEffect());
       
        // or Permanents you control can't be the targets of blue or black spells your opponents control this turn.
        Mode mode = new Mode();
        mode.getEffects().add(new CantBeTargetedAllEffect(new FilterControlledPermanent(), filterSource, Duration.EndOfTurn));
        this.getSpellAbility().getModes().addMode(mode);
    }

    public DisplayOfDominance(final DisplayOfDominance card) {
        super(card);
    }

    @Override
    public DisplayOfDominance copy() {
        return new DisplayOfDominance(this);
    }
}
Try to use FilterStackObject instead of FilterSpell.
jeffwadsworth
Super Tester Elite
 
Posts: 1172
Joined: 20 Oct 2010, 04:47
Location: USA
Has thanked: 287 times
Been thanked: 70 times

Re: New set Dragons of Tarkir

Postby jeffwadsworth » 10 Mar 2015, 16:30

fireshoes wrote:
jeffwadsworth wrote:You will need something like TargetCreatureOrPlaneswalkerAmount(). Try this code.

Code: Select all
/*
 * 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.target.common;

import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import mage.constants.Zone;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.dynamicvalue.common.StaticValue;
import mage.filter.Filter;
import mage.filter.common.FilterCreatureOrPlaneswalkerPermanent;
import mage.filter.common.FilterCreaturePermanent;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.target.TargetAmount;

/**
 *
 * @author BetaSteward_at_googlemail.com
 */
public class TargetCreatureOrPlaneswalkerAmount extends TargetAmount {

    protected FilterCreatureOrPlaneswalkerPermanent filter;

    public TargetCreatureOrPlaneswalkerAmount(int amount) {
        // 107.1c If a rule or ability instructs a player to choose “any number,” that player may choose
        // any positive number or zero, unless something (such as damage or counters) is being divided
        // or distributed among “any number” of players and/or objects. In that case, a nonzero number
        // of players and/or objects must be chosen if possible.
        this(new StaticValue(amount));
        this.minNumberOfTargets = 1;
    }

    public TargetCreatureOrPlaneswalkerAmount(DynamicValue amount) {
        super(amount);
        this.zone = Zone.ALL;
        this.filter = new FilterCreatureOrPlaneswalkerPermanent();
        this.targetName = filter.getMessage();
    }

    public TargetCreatureOrPlaneswalkerAmount(final TargetCreatureOrPlaneswalkerAmount target) {
        super(target);
        this.filter = target.filter.copy();
    }

    @Override
    public Filter getFilter() {
        return this.filter;
    }

    @Override
    public boolean canTarget(UUID id, Game game) {
        Permanent permanent = game.getPermanent(id);
        if (permanent != null) {
            return filter.match(permanent, game);
        }
        return false;
    }

    @Override
    public boolean canTarget(UUID id, Ability source, Game game) {
        Permanent permanent = game.getPermanent(id);
        if (source != null) {
            MageObject targetSource = game.getObject(source.getSourceId());
            if (permanent != null) {
                return permanent.canBeTargetedBy(targetSource, source.getControllerId(), game) && filter.match(permanent, source.getSourceId(), source.getControllerId(), game);
            }
        }

        if (permanent != null) {
            return filter.match(permanent, game);
        }
        return false;
    }

    @Override
    public boolean canTarget(UUID playerId, UUID id, Ability source, Game game) {
        return canTarget(id, source, game);
    }

    @Override
    public boolean canChoose(UUID sourceId, UUID sourceControllerId, Game game) {
        int count = 0;
        MageObject targetSource = game.getObject(sourceId);
        for (Permanent permanent : game.getBattlefield().getActivePermanents(new FilterCreaturePermanent(), sourceControllerId, game)) {
            if (permanent.canBeTargetedBy(targetSource, sourceControllerId, game) && filter.match(permanent, sourceId, sourceControllerId, game)) {
                count++;
                if (count >= this.minNumberOfTargets) {
                    return true;
                }
            }
        }
        return false;
    }

    @Override
    public boolean canChoose(UUID sourceControllerId, Game game) {
        int count = 0;
        for (Permanent permanent : game.getBattlefield().getActivePermanents(new FilterCreaturePermanent(), sourceControllerId, game)) {
            if (filter.match(permanent, null, sourceControllerId, game)) {
                count++;
                if (count >= this.minNumberOfTargets) {
                    return true;
                }
            }
        }
        return false;
    }

    @Override
    public Set<UUID> possibleTargets(UUID sourceId, UUID sourceControllerId, Game game) {
        Set<UUID> possibleTargets = new HashSet<>();
        MageObject targetSource = game.getObject(sourceId);
        for (Permanent permanent : game.getBattlefield().getActivePermanents(new FilterCreaturePermanent(), sourceControllerId, game)) {
            if (permanent.canBeTargetedBy(targetSource, sourceControllerId, game) && filter.match(permanent, sourceId, sourceControllerId, game)) {
                possibleTargets.add(permanent.getId());
            }
        }
        return possibleTargets;
    }

    @Override
    public Set<UUID> possibleTargets(UUID sourceControllerId, Game game) {
        Set<UUID> possibleTargets = new HashSet<>();
        for (Permanent permanent : game.getBattlefield().getActivePermanents(new FilterCreaturePermanent(), sourceControllerId, game)) {
            if (filter.match(permanent, null, sourceControllerId, game)) {
                possibleTargets.add(permanent.getId());
            }
        }
        return possibleTargets;
    }

    @Override
    public String getTargetedName(Game game) {
        StringBuilder sb = new StringBuilder();
        for (UUID targetId : getTargets()) {
            Permanent permanent = game.getPermanent(targetId);
            if (permanent != null) {
                sb.append(permanent.getLogName()).append("(").append(getTargetAmount(targetId)).append(") ");
            }
        }
        return sb.toString();
    }

    @Override
    public TargetCreatureOrPlaneswalkerAmount copy() {
        return new TargetCreatureOrPlaneswalkerAmount(this);
    }

}
This worked good, except am I able to filter it to target only creatures and planeswalkers my opponents control?
You can try adding this.filter.add(new ControllerPredicate(TargetController.OPPONENT)); underneath the this.filter = new FilterCreatureOrPlaneswalkerPermanent(); at the top.
jeffwadsworth
Super Tester Elite
 
Posts: 1172
Joined: 20 Oct 2010, 04:47
Location: USA
Has thanked: 287 times
Been thanked: 70 times

Re: New set Dragons of Tarkir

Postby jeffwadsworth » 10 Mar 2015, 16:38

fireshoes wrote:Self-Inflicted Wound Target opponent sacrifices a green or white creature. If that player does, he or she loses 2 life.

What's the best way to check to see if the player sacrificed a creature?
Look at Warren Weirding.
jeffwadsworth
Super Tester Elite
 
Posts: 1172
Joined: 20 Oct 2010, 04:47
Location: USA
Has thanked: 287 times
Been thanked: 70 times

Re: New set Dragons of Tarkir

Postby jeffwadsworth » 11 Mar 2015, 22:07

Here is some code for Dragon Tempest. I put it all under one trigger due to a "null" error that would pop up during the game when triggers would attempt to resolve. If someone can make it work, please do.

Code: Select all
/*
 *  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.sets.dragonsoftarkir;

import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.InfoEffect;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.abilities.keyword.HasteAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.filter.common.FilterControlledPermanent;
import mage.filter.predicate.mageobject.SubtypePredicate;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetCreatureOrPlayer;
import mage.target.targetpointer.FixedTarget;

/**
 *
 * @author ANYONE THAT CAN GET THIS THING TO WORK!!  It would be nice to use 2 triggers, but good luck.
 */
public class DragonTempest extends CardImpl {
   
    private static final String rule = "Whenever a creature with flying enters the battlefield under your control, it gains haste until the end of turn.";
    private static final String rule2 = "Whenever a Dragon enters the battlefield under your control, it deals X damage to target creature or player, where X is the number of Dragons you control.";

    public DragonTempest(UUID ownerId) {
        super(ownerId, 136, "Dragon Tempest", Rarity.RARE, new CardType[]{CardType.ENCHANTMENT}, "{1}{R}");
        this.expansionSetCode = "DTK";

        // Whenever a creature with flying enters the battlefield under your control, it gains haste until the end of turn.
        // Whenever a Dragon enters the battlefield under your control, it deals X damage to target creature or player, where X is the number of Dragons you control.
        Ability ability = new DragonTempestTriggeredAbility();
        ability.addEffect(new InfoEffect(rule));
        ability.addEffect(new InfoEffect(rule2));
        this.addAbility(ability);

    }

    public DragonTempest(final DragonTempest card) {
        super(card);
    }

    @Override
    public DragonTempest copy() {
        return new DragonTempest(this);
    }
}

class DragonTempestTriggeredAbility extends TriggeredAbilityImpl {

    boolean applied = false;

    public DragonTempestTriggeredAbility() {
        super(Zone.BATTLEFIELD, null);
    }

    public DragonTempestTriggeredAbility(DragonTempestTriggeredAbility ability) {
        super(ability);
    }

    @Override
    public boolean checkTrigger(GameEvent event, Game game) {
        if (event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD) {
            Permanent permanent = game.getPermanent(event.getTargetId());
            if (permanent != null
                    && permanent.getControllerId().equals(controllerId)
                    && permanent.getSubtype().contains("Dragon")) {
                game.getState().setValue("damageSource", event.getTargetId());
                new DragonTempestEffect().apply(game, this);
                applied = true;
            }
            if (permanent != null
                    && permanent.getControllerId().equals(this.controllerId)
                    && permanent.getAbilities().contains(FlyingAbility.getInstance())) {
                ContinuousEffect effect = new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn);
                effect.setTargetPointer(new FixedTarget(event.getTargetId()));
                game.addEffect(effect, this);
                applied = true;
            }
        }
        return applied;
    }

    @Override
    public DragonTempestTriggeredAbility copy() {
        return new DragonTempestTriggeredAbility(this);
    }
}

class DragonTempestEffect extends OneShotEffect {

    private static final FilterControlledPermanent dragonFilter = new FilterControlledPermanent();

    static {
        dragonFilter.add(new SubtypePredicate("Dragon"));
    }

    public DragonTempestEffect() {
        super(Outcome.Damage);
    }

    public DragonTempestEffect(final DragonTempestEffect effect) {
        super(effect);
    }

    @Override
    public DragonTempestEffect copy() {
        return new DragonTempestEffect(this);
    }

    @Override
    public boolean apply(Game game, Ability source) {
        Player controller = game.getPlayer(source.getControllerId());
        TargetCreatureOrPlayer target = new TargetCreatureOrPlayer();
        if (controller != null) {
            if (controller.choose(Outcome.Damage, target, source.getSourceId(), game)
                    && target.canChoose(controller.getId(), game)) {
                UUID dragonId = (UUID) game.getState().getValue("damageSource");
                Permanent dragon = game.getPermanentOrLKIBattlefield(dragonId);
                if (dragon != null) {
                    int amount = game.getBattlefield().countAll(dragonFilter, controller.getId(), game);
                    UUID targetId = target.getFirstTarget();
                    Permanent targetCreature = game.getPermanent(targetId);
                    if (targetCreature != null) {
                        targetCreature.damage(amount, dragon.getId(), game, false, true);
                    } else {
                        Player player = game.getPlayer(targetId);
                        if (player != null) {
                            player.damage(amount, dragon.getId(), game, false, true);
                        }
                    }
                    return true;
                }
            }
        }
        return false;
    }
}
jeffwadsworth
Super Tester Elite
 
Posts: 1172
Joined: 20 Oct 2010, 04:47
Location: USA
Has thanked: 287 times
Been thanked: 70 times

Re: New set Dragons of Tarkir

Postby LevelX » 12 Mar 2015, 02:22

jeffwadsworth wrote:Here is some code for Dragon Tempest. I put it all under one trigger due to a "null" error that would pop up during the game when triggers would attempt to resolve. If someone can make it work, please do.
I added the card to the git repository.
There are problems with the display of the triggered abilities that I'm investigating (the null message you mentioned).
But that problem is not the cards fault.
User avatar
LevelX
DEVELOPER
 
Posts: 1677
Joined: 08 Dec 2011, 15:08
Has thanked: 174 times
Been thanked: 374 times

Re: New set Dragons of Tarkir

Postby fireshoes » 12 Mar 2015, 02:33

Does Display of Dominance (above) look ok to you? I made the change to FilterStackObject as Jeff suggested and am still getting a NPE when the opponent's spell tries to resolve.
User avatar
fireshoes
 
Posts: 536
Joined: 20 Aug 2014, 03:51
Has thanked: 201 times
Been thanked: 49 times

Re: New set Dragons of Tarkir

Postby LevelX » 12 Mar 2015, 16:13

fireshoes wrote:Does Display of Dominance (above) look ok to you? I made the change to FilterStackObject as Jeff suggested and am still getting a NPE when the opponent's spell tries to resolve.
Is the problem gone now, with the fix of null pointer exception for tooltip and triggered abilities i committed?

I had a look of the code of Display of Dominance and it looked good to me.
User avatar
LevelX
DEVELOPER
 
Posts: 1677
Joined: 08 Dec 2011, 15:08
Has thanked: 174 times
Been thanked: 374 times

Re: New set Dragons of Tarkir

Postby fireshoes » 12 Mar 2015, 16:40

Still having a problem. Mage Client was all I needed to do a build on for the update to be in place, right?

Here's the NPE for Hero's Downfall targeting Courser of Kruphix:
Code: Select all
Game exception occurred: java.lang.NullPointerException
Server version: 1.3.0
mage.filter.predicate.permanent.ControllerPredicate.apply(ControllerPredicate.java:62)
mage.filter.predicate.permanent.ControllerPredicate.apply(ControllerPredicate.java:42)
mage.filter.predicate.Predicates$AndPredicate.apply(Predicates.java:172)
mage.filter.FilterStackObject.match(FilterStackObject.java:67)
mage.abilities.effects.common.CantBeTargetedAllEffect.applies(CantBeTargetedAllEffect.java:98)
mage.abilities.effects.ContinuousEffects.preventedByRuleModification(ContinuousEffects.java:665)
mage.game.GameState.replaceEvent(GameState.java:531)
mage.game.GameImpl.replaceEvent(GameImpl.java:2069)
mage.target.TargetImpl.isLegal(TargetImpl.java:339)
mage.target.Targets.stillLegal(Targets.java:113)
mage.game.stack.Spell.spellAbilityHasLegalParts(Spell.java:296)
mage.game.stack.Spell.resolve(Spell.java:189)
mage.game.GameImpl.resolve(GameImpl.java:1195)
mage.game.GameImpl.playPriority(GameImpl.java:1157)
mage.game.turn.Step.priority(Step.java:87)
mage.game.turn.Phase.playStep(Phase.java:203)
mage.game.turn.Phase.play(Phase.java:115)
mage.game.turn.Turn.play(Turn.java:140)
mage.game.GameImpl.playTurn(GameImpl.java:734)
mage.game.GameImpl.play(GameImpl.java:659)
mage.game.GameImpl.start(GameImpl.java:626)
mage.game.GameImpl.start(GameImpl.java:611)
mage.server.game.GameWorker.call(GameWorker.java:60)
java.util.concurrent.FutureTask.run(FutureTask.java:262)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
java.lang.Thread.run(Thread.java:745)
It rewinds, Computer casts Downfall again and if I don't cast Display of Dominance, no NPE occurs.
User avatar
fireshoes
 
Posts: 536
Joined: 20 Aug 2014, 03:51
Has thanked: 201 times
Been thanked: 49 times

Re: New set Dragons of Tarkir

Postby LevelX » 12 Mar 2015, 16:47

fireshoes wrote:Still having a problem. Mage Client was all I needed to do a build on for the update to be in place, right?

It rewinds, Computer casts Downfall again and if I don't cast Display of Dominance, no NPE occurs.
If you build with dependencies - I guess yes.
User avatar
LevelX
DEVELOPER
 
Posts: 1677
Joined: 08 Dec 2011, 15:08
Has thanked: 174 times
Been thanked: 374 times

Re: New set Dragons of Tarkir

Postby fireshoes » 12 Mar 2015, 16:52

Posting my partial code for Narset here if anyone wants to work on it. I'm not expecting to have much free time the next few days because I'm moving, and I know people will be disappointed if she isn't included with the next update.

Her +1 is working. I haven't have started her -2. Her -9 is partially coded. I've been using Silence and Aurelia's Fury as a guideline. The emblem appears, but it doesn't actually stop the opponent from casting anything. I think a little tweaking of the last bit of code will fix it.

Code: Select all
/*
 *  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.sets.dragonsoftarkir;

import java.util.UUID;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility;
import mage.abilities.common.EntersBattlefieldAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.ContinuousRuleModifyingEffectImpl;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.GetEmblemEffect;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardsImpl;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.constants.TargetController;
import mage.constants.Zone;
import mage.counters.CounterType;
import mage.filter.FilterSpell;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.filter.predicate.permanent.ControllerPredicate;
import mage.game.Game;
import mage.game.command.Emblem;
import mage.game.events.GameEvent;
import mage.players.Player;

/**
 *
 * @author fireshoes
 */
public class NarsetTranscendent extends CardImpl {
   
    private static final FilterSpell filter = new FilterSpell("instant and sorcery spells you control");

    static {
        filter.add(Predicates.or(new CardTypePredicate(CardType.INSTANT), new CardTypePredicate(CardType.SORCERY)));
        filter.add(new ControllerPredicate(TargetController.YOU));
    }

    public NarsetTranscendent(UUID ownerId) {
        super(ownerId, 225, "Narset Transcendent", Rarity.MYTHIC, new CardType[]{CardType.PLANESWALKER}, "{2}{W}{U}");
        this.expansionSetCode = "DTK";
        this.subtype.add("Narset");
       
        this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(6)), false));

        // +1: Look at the top card of your library. If it's a noncreature, nonland card, you may reveal it and put it into your hand.
        this.addAbility(new LoyaltyAbility(new NarsetTranscendentLibraryEffect(), 1));
       
     /*   // -2: When you cast your next instant or sorcery spell from your hand this turn, it gains rebound.
        /*this.addAbility(new LoyaltyAbility(new NarsetTranscendentReboundEffect(), -2));*/
       
        // -9:You get an emblem with "Your opponents can't cast noncreature spells."
        this.addAbility(new LoyaltyAbility(new GetEmblemEffect(new NarsetTranscendentEmblem()), -9));
    }

    public NarsetTranscendent(final NarsetTranscendent card) {
        super(card);
    }

    @Override
    public NarsetTranscendent copy() {
        return new NarsetTranscendent(this);
    }
}

class NarsetTranscendentLibraryEffect extends OneShotEffect {

    public NarsetTranscendentLibraryEffect() {
        super(Outcome.DrawCard);
        this.staticText = "Look at the top card of your library. If it's a noncreature, nonland card, you may reveal it and put it into your hand";
    }

    public NarsetTranscendentLibraryEffect(final NarsetTranscendentLibraryEffect effect) {
        super(effect);
    }

    @Override
    public NarsetTranscendentLibraryEffect copy() {
        return new NarsetTranscendentLibraryEffect(this);
    }

    @Override
    public boolean apply(Game game, Ability source) {
        Player controller = game.getPlayer(source.getControllerId());
        if (controller != null && controller.getLibrary().size() > 0) {
            Card card = controller.getLibrary().getFromTop(game);
            if (card != null) {
                CardsImpl cards = new CardsImpl();
                cards.add(card);
                controller.lookAtCards("Narset Transcendent", cards, game);
                if (!card.getCardType().contains(CardType.CREATURE)
                    && (!card.getCardType().contains(CardType.LAND))){
                    if (controller.chooseUse(outcome, new StringBuilder("Reveal ").append(card.getName()).append(" and put it into your hand?").toString(), game)) {
                        card = controller.getLibrary().removeFromTop(game);
                        controller.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.LIBRARY);
                        controller.revealCards("Narset Transcendent", cards, game);
                    }
                }
                return true;
            }
        }
        return false;
    }
}

class NarsetTranscendentEmblem extends Emblem {
    // "Your opponents can't cast noncreature spells."
    public NarsetTranscendentEmblem() {
        this.setName("EMBLEM: Narset Transcendent");
       this.getAbilities().add(new SimpleStaticAbility(Zone.COMMAND, new NarsetTranscendentCantCastEffect()));
    }
}

class NarsetTranscendentCantCastEffect extends ContinuousRuleModifyingEffectImpl {

    public NarsetTranscendentCantCastEffect() {
        super(Duration.EndOfGame, Outcome.Benefit);
        staticText = "Your opponents can't cast noncreature spells";
    }

    public NarsetTranscendentCantCastEffect(final NarsetTranscendentCantCastEffect effect) {
        super(effect);
    }

    @Override
    public NarsetTranscendentCantCastEffect copy() {
        return new NarsetTranscendentCantCastEffect(this);
    }

    @Override
    public boolean apply(Game game, Ability source) {
        return true;
    }

    @Override
    public String getInfoMessage(Ability source, GameEvent event, Game game) {
        MageObject mageObject = game.getObject(source.getSourceId());
        if (mageObject != null) {
            return "You can't cast noncreature spells (" + mageObject.getLogName() + ").";
        }
        return null;
    }
   
    @Override
    public boolean applies(GameEvent event, Ability source, Game game) {
        if (event.getType() == GameEvent.EventType.CAST_SPELL ) {
            Player player = game.getPlayer(getTargetPointer().getFirst(game, source));
            if (player != null && game.getOpponents(source.getControllerId()).contains(event.getPlayerId())) {
                Card card = game.getCard(event.getSourceId());
                if (card != null && !card.getCardType().contains(CardType.CREATURE)) {
                    return true;
                }
            }
        }
        return false;
    }
}
User avatar
fireshoes
 
Posts: 536
Joined: 20 Aug 2014, 03:51
Has thanked: 201 times
Been thanked: 49 times

Re: New set Dragons of Tarkir

Postby fireshoes » 12 Mar 2015, 16:55

Ah, I just did Build, so maybe it is ok. I have to leave now, so I will maybe get to look at it in 5 or 6 hours.
User avatar
fireshoes
 
Posts: 536
Joined: 20 Aug 2014, 03:51
Has thanked: 201 times
Been thanked: 49 times

Re: New set Dragons of Tarkir

Postby jeffwadsworth » 12 Mar 2015, 22:23

fireshoes wrote:Posting my partial code for Narset here if anyone wants to work on it. I'm not expecting to have much free time the next few days because I'm moving, and I know people will be disappointed if she isn't included with the next update.

Her +1 is working. I haven't have started her -2. Her -9 is partially coded. I've been using Silence and Aurelia's Fury as a guideline. The emblem appears, but it doesn't actually stop the opponent from casting anything. I think a little tweaking of the last bit of code will fix it.

Code: Select all
/*
 *  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.sets.dragonsoftarkir;

import java.util.UUID;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility;
import mage.abilities.common.EntersBattlefieldAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.ContinuousRuleModifyingEffectImpl;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.GetEmblemEffect;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardsImpl;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.constants.TargetController;
import mage.constants.Zone;
import mage.counters.CounterType;
import mage.filter.FilterSpell;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.filter.predicate.permanent.ControllerPredicate;
import mage.game.Game;
import mage.game.command.Emblem;
import mage.game.events.GameEvent;
import mage.players.Player;

/**
 *
 * @author fireshoes
 */
public class NarsetTranscendent extends CardImpl {
   
    private static final FilterSpell filter = new FilterSpell("instant and sorcery spells you control");

    static {
        filter.add(Predicates.or(new CardTypePredicate(CardType.INSTANT), new CardTypePredicate(CardType.SORCERY)));
        filter.add(new ControllerPredicate(TargetController.YOU));
    }

    public NarsetTranscendent(UUID ownerId) {
        super(ownerId, 225, "Narset Transcendent", Rarity.MYTHIC, new CardType[]{CardType.PLANESWALKER}, "{2}{W}{U}");
        this.expansionSetCode = "DTK";
        this.subtype.add("Narset");
       
        this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(6)), false));

        // +1: Look at the top card of your library. If it's a noncreature, nonland card, you may reveal it and put it into your hand.
        this.addAbility(new LoyaltyAbility(new NarsetTranscendentLibraryEffect(), 1));
       
     /*   // -2: When you cast your next instant or sorcery spell from your hand this turn, it gains rebound.
        /*this.addAbility(new LoyaltyAbility(new NarsetTranscendentReboundEffect(), -2));*/
       
        // -9:You get an emblem with "Your opponents can't cast noncreature spells."
        this.addAbility(new LoyaltyAbility(new GetEmblemEffect(new NarsetTranscendentEmblem()), -9));
    }

    public NarsetTranscendent(final NarsetTranscendent card) {
        super(card);
    }

    @Override
    public NarsetTranscendent copy() {
        return new NarsetTranscendent(this);
    }
}

class NarsetTranscendentLibraryEffect extends OneShotEffect {

    public NarsetTranscendentLibraryEffect() {
        super(Outcome.DrawCard);
        this.staticText = "Look at the top card of your library. If it's a noncreature, nonland card, you may reveal it and put it into your hand";
    }

    public NarsetTranscendentLibraryEffect(final NarsetTranscendentLibraryEffect effect) {
        super(effect);
    }

    @Override
    public NarsetTranscendentLibraryEffect copy() {
        return new NarsetTranscendentLibraryEffect(this);
    }

    @Override
    public boolean apply(Game game, Ability source) {
        Player controller = game.getPlayer(source.getControllerId());
        if (controller != null && controller.getLibrary().size() > 0) {
            Card card = controller.getLibrary().getFromTop(game);
            if (card != null) {
                CardsImpl cards = new CardsImpl();
                cards.add(card);
                controller.lookAtCards("Narset Transcendent", cards, game);
                if (!card.getCardType().contains(CardType.CREATURE)
                    && (!card.getCardType().contains(CardType.LAND))){
                    if (controller.chooseUse(outcome, new StringBuilder("Reveal ").append(card.getName()).append(" and put it into your hand?").toString(), game)) {
                        card = controller.getLibrary().removeFromTop(game);
                        controller.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.LIBRARY);
                        controller.revealCards("Narset Transcendent", cards, game);
                    }
                }
                return true;
            }
        }
        return false;
    }
}

class NarsetTranscendentEmblem extends Emblem {
    // "Your opponents can't cast noncreature spells."
    public NarsetTranscendentEmblem() {
        this.setName("EMBLEM: Narset Transcendent");
       this.getAbilities().add(new SimpleStaticAbility(Zone.COMMAND, new NarsetTranscendentCantCastEffect()));
    }
}

class NarsetTranscendentCantCastEffect extends ContinuousRuleModifyingEffectImpl {

    public NarsetTranscendentCantCastEffect() {
        super(Duration.EndOfGame, Outcome.Benefit);
        staticText = "Your opponents can't cast noncreature spells";
    }

    public NarsetTranscendentCantCastEffect(final NarsetTranscendentCantCastEffect effect) {
        super(effect);
    }

    @Override
    public NarsetTranscendentCantCastEffect copy() {
        return new NarsetTranscendentCantCastEffect(this);
    }

    @Override
    public boolean apply(Game game, Ability source) {
        return true;
    }

    @Override
    public String getInfoMessage(Ability source, GameEvent event, Game game) {
        MageObject mageObject = game.getObject(source.getSourceId());
        if (mageObject != null) {
            return "You can't cast noncreature spells (" + mageObject.getLogName() + ").";
        }
        return null;
    }
   
    @Override
    public boolean applies(GameEvent event, Ability source, Game game) {
        if (event.getType() == GameEvent.EventType.CAST_SPELL ) {
            Player player = game.getPlayer(getTargetPointer().getFirst(game, source));
            if (player != null && game.getOpponents(source.getControllerId()).contains(event.getPlayerId())) {
                Card card = game.getCard(event.getSourceId());
                if (card != null && !card.getCardType().contains(CardType.CREATURE)) {
                    return true;
                }
            }
        }
        return false;
    }
}
I will look at it unless someone speaks up.

Update: Well, the third ability was a straight-forward fix, but the second ability is not working to my satisfaction. I would like to use a CAST_SPELL trigger and place the ability on the card before it hits the stack, but this is not working very well for me. Anyway, here is the code for the 3rd ability. A better coder will have to implement that 2nd ability.

Code: Select all
class NarsetTranscendentEmblem extends Emblem {

    // "Your opponents can't cast noncreature spells."
    public NarsetTranscendentEmblem() {
        this.setName("EMBLEM: Narset Transcendent");
        this.getAbilities().add(new SimpleStaticAbility(Zone.COMMAND, new NarsetTranscendentCantCastEffect()));
    }
}

class NarsetTranscendentCantCastEffect extends ContinuousRuleModifyingEffectImpl {
   
    public NarsetTranscendentCantCastEffect() {
        super(Duration.EndOfGame, Outcome.Benefit);
        staticText = "Your opponents can't cast noncreature spells";
    }
   
    public NarsetTranscendentCantCastEffect(final NarsetTranscendentCantCastEffect effect) {
        super(effect);
    }
   
    @Override
    public NarsetTranscendentCantCastEffect copy() {
        return new NarsetTranscendentCantCastEffect(this);
    }
   
    @Override
    public boolean apply(Game game, Ability source) {
        return true;
    }
   
    @Override
    public String getInfoMessage(Ability source, GameEvent event, Game game) {
        MageObject mageObject = game.getObject(source.getSourceId());
        if (mageObject != null) {
            return "You can't cast noncreature spells (" + mageObject.getLogName() + ").";
        }
        return null;
    }
   
    @Override
    public boolean checksEventType(GameEvent event, Game game) {
        return event.getType() == GameEvent.EventType.CAST_SPELL;
    }
   
    @Override
    public boolean applies(GameEvent event, Ability source, Game game) {
        Player controller = game.getPlayer(source.getControllerId());
        Card card = game.getCard(event.getSourceId());
        return (controller != null
                && game.getOpponents(source.getControllerId()).contains(event.getPlayerId())
                && !card.getCardType().contains(CardType.CREATURE));
    }
}
Last edited by jeffwadsworth on 13 Mar 2015, 20:40, edited 1 time in total.
jeffwadsworth
Super Tester Elite
 
Posts: 1172
Joined: 20 Oct 2010, 04:47
Location: USA
Has thanked: 287 times
Been thanked: 70 times

Re: New set Dragons of Tarkir

Postby JotaPeRL » 13 Mar 2015, 11:45

LevelX wrote:Is the problem gone now, with the fix of null pointer exception for tooltip and triggered abilities i committed?
It's not gone. It's different. Now I can't even see the starting hand. NPE anytime the client tries to display a card. Deck editor and game scene not working, at least for me.
JotaPeRL
 
Posts: 11
Joined: 18 Nov 2013, 13:01
Has thanked: 1 time
Been thanked: 0 time

Re: New set Dragons of Tarkir

Postby LevelX » 13 Mar 2015, 12:23

JotaPeRL wrote:
LevelX wrote:Is the problem gone now, with the fix of null pointer exception for tooltip and triggered abilities i committed?
It's not gone. It's different. Now I can't even see the starting hand. NPE anytime the client tries to display a card. Deck editor and game scene not working, at least for me.
And you really did a "Clean and build" on "Mage Root" project?
User avatar
LevelX
DEVELOPER
 
Posts: 1677
Joined: 08 Dec 2011, 15:08
Has thanked: 174 times
Been thanked: 374 times

PreviousNext

Return to Developers Talk

Who is online

Users browsing this forum: No registered users and 3 guests

Main Menu

User Menu

Our Partners


Who is online

In total there are 3 users online :: 0 registered, 0 hidden and 3 guests (based on users active over the past 10 minutes)
Most users ever online was 7303 on 15 Jul 2025, 20:46

Users browsing this forum: No registered users and 3 guests

Login Form