It is currently 04 Nov 2025, 15:56
   
Text Size

Help implementing a card

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

Re: Help implementing a card

Postby cbt33 » 31 Aug 2013, 19:41

I had read much of that before but from another post I had gotten the impression you only needed to build once and could edit that.

The reason the build was taking so long was strictly because of the tests but when I removed the Mage.Tests module it only takes 6 minutes or so and was still successful. There's no downside to doing this is there?
cbt33
 
Posts: 11
Joined: 24 Aug 2012, 01:32
Has thanked: 3 times
Been thanked: 0 time

Re: Help implementing a card

Postby LevelX » 01 Sep 2013, 06:19

cbt33 wrote:I had read much of that before but from another post I had gotten the impression you only needed to build once and could edit that.
The changed projects have to be rebuild. But normally that's very fast, needing only some seconds. There also exist an "compile on save" option in Netbeans, but that leads to errors under some circumstances and it's better to deactivate it.

cbt33 wrote:The reason the build was taking so long was strictly because of the tests but when I removed the Mage.Tests module it only takes 6 minutes or so and was still successful. There's no downside to doing this is there?
Yes, you don't have to rebuild the tests after every change. It's good practice to build them before you commit changes to the remote repository, to check if your changes broke some exiting tests.
User avatar
LevelX
DEVELOPER
 
Posts: 1677
Joined: 08 Dec 2011, 15:08
Has thanked: 174 times
Been thanked: 374 times

Re: Help implementing a card

Postby cbt33 » 16 Sep 2013, 19:37

Here are ten or so for Odyssey. I didn't test the threshold code on Divine Sacrament but it came from an existing card. Each one is from Odyssey except for BlessedOrator.java for which gen-card.pl placed the main card in Ninth extended in Odyssey.

A last problem I have is that the cards that are in init.txt don't appear when I press the cheat button. Are they also supposed to have the set prefix that are in .dck files?
Attachments
odyssey.zip
(20.35 KiB) Downloaded 346 times
cbt33
 
Posts: 11
Joined: 24 Aug 2012, 01:32
Has thanked: 3 times
Been thanked: 0 time

Re: Help implementing a card

Postby LevelX » 16 Sep 2013, 22:35

cbt33 wrote:A last problem I have is that the cards that are in init.txt don't appear when I press the cheat button. Are they also supposed to have the set prefix that are in .dck files?
NO, the may not have a set prefix.
Did you use the correct name of the player in init.txt?
What does the server log output show about the init.txt parse, if you push the cheat button?
User avatar
LevelX
DEVELOPER
 
Posts: 1677
Joined: 08 Dec 2011, 15:08
Has thanked: 174 times
Been thanked: 374 times

Re: Help implementing a card

Postby LevelX » 16 Sep 2013, 22:43

cbt33 wrote:Here are ten or so for Odyssey. I didn't test the threshold code on Divine Sacrament but it came from an existing card. Each one is from Odyssey except for BlessedOrator.java for which gen-card.pl placed the main card in Ninth extended in Odyssey.
I merged the cards to the repository using the pull request.
I will take a look tomorrow on the cards, if I see something to improve or change I will comment it in the pull request issue.

Thanks a lot for your efforts.
I hope to see some more cards implemented by you.
:-)
User avatar
LevelX
DEVELOPER
 
Posts: 1677
Joined: 08 Dec 2011, 15:08
Has thanked: 174 times
Been thanked: 374 times

Re: Help implementing a card

Postby cbt33 » 17 Sep 2013, 02:14

This is what is in the server output from when it parses init.txt on (I sign into the server as cbt)

INFO [2013-09-10 02:52 [40:708]] SystemUtil[pool-2-thread-2]: Parsing init.txt...
WARN [2013-09-10 02:52 [40:720]] SystemUtil[pool-2-thread-2]: Was skipped: battlefield:cbt:Mountain:3
WARN [2013-09-10 02:52 [40:721]] SystemUtil[pool-2-thread-2]: Was skipped: graveyard:cbt:Plains:1
WARN [2013-09-10 02:52 [40:721]] SystemUtil[pool-2-thread-2]: Was skipped: battlefield:cbt:Cephalid Broker:1
WARN [2013-09-10 02:52 [40:721]] SystemUtil[pool-2-thread-2]: Was skipped: battlefield:cbt:Megrim:1
WARN [2013-09-10 02:52 [40:722]] SystemUtil[pool-2-thread-2]: Was skipped: battlefield:cbt:Island:2
WARN [2013-09-10 02:52 [40:722]] SystemUtil[pool-2-thread-2]: Was skipped: battlefield:cbt:Plains:3
WARN [2013-09-10 02:52 [40:722]] SystemUtil[pool-2-thread-2]: Was skipped: hand:cbt:Whispersilk Cloak:1
WARN [2013-09-10 02:52 [40:723]] SystemUtil[pool-2-thread-2]: Was skipped: hand:cbt:Lightning Bolt:1
WARN [2013-09-10 02:52 [40:723]] SystemUtil[pool-2-thread-2]: Was skipped: library:cbt:Shock:2

I also get a long list of errors like these for what comes out of cheat.dck but those enter the battlefield just fine.

WARN [2013-09-10 02:52 [40:644]] CardImpl[pool-2-thread-2]: putOntoBattlefield, not fully implemented: fromZone=OUTSIDE
WARN [2013-09-10 02:52 [40:644]] CardImpl[pool-2-thread-2]: Couldn't find card in fromZone, card=Forest, fromZone=OUTSIDE
WARN [2013-09-10 02:52 [40:646]] CardImpl[pool-2-thread-2]: putOntoBattlefield, not fully implemented: fromZone=OUTSIDE
WARN [2013-09-10 02:52 [40:646]] CardImpl[pool-2-thread-2]: Couldn't find card in fromZone, card=Forest, fromZone=OUTSIDE
cbt33
 
Posts: 11
Joined: 24 Aug 2012, 01:32
Has thanked: 3 times
Been thanked: 0 time

Re: Help implementing a card

Postby LevelX » 17 Sep 2013, 06:28

cbt33 wrote:This is what is in the server output from when it parses init.txt on (I sign into the server as cbt)

INFO [2013-09-10 02:52 [40:708]] SystemUtil[pool-2-thread-2]: Parsing init.txt...
WARN [2013-09-10 02:52 [40:720]] SystemUtil[pool-2-thread-2]: Was skipped: battlefield:cbt:Mountain:3
WARN [2013-09-10 02:52 [40:721]] SystemUtil[pool-2-thread-2]: Was skipped: graveyard:cbt:Plains:1
WARN [2013-09-10 02:52 [40:721]] SystemUtil[pool-2-thread-2]: Was skipped: battlefield:cbt:Cephalid Broker:1
WARN [2013-09-10 02:52 [40:721]] SystemUtil[pool-2-thread-2]: Was skipped: battlefield:cbt:Megrim:1
WARN [2013-09-10 02:52 [40:722]] SystemUtil[pool-2-thread-2]: Was skipped: battlefield:cbt:Island:2
WARN [2013-09-10 02:52 [40:722]] SystemUtil[pool-2-thread-2]: Was skipped: battlefield:cbt:Plains:3
WARN [2013-09-10 02:52 [40:722]] SystemUtil[pool-2-thread-2]: Was skipped: hand:cbt:Whispersilk Cloak:1
WARN [2013-09-10 02:52 [40:723]] SystemUtil[pool-2-thread-2]: Was skipped: hand:cbt:Lightning Bolt:1
WARN [2013-09-10 02:52 [40:723]] SystemUtil[pool-2-thread-2]: Was skipped: library:cbt:Shock:2

I also get a long list of errors like these for what comes out of cheat.dck but those enter the battlefield just fine.

WARN [2013-09-10 02:52 [40:644]] CardImpl[pool-2-thread-2]: putOntoBattlefield, not fully implemented: fromZone=OUTSIDE
WARN [2013-09-10 02:52 [40:644]] CardImpl[pool-2-thread-2]: Couldn't find card in fromZone, card=Forest, fromZone=OUTSIDE
WARN [2013-09-10 02:52 [40:646]] CardImpl[pool-2-thread-2]: putOntoBattlefield, not fully implemented: fromZone=OUTSIDE
WARN [2013-09-10 02:52 [40:646]] CardImpl[pool-2-thread-2]: Couldn't find card in fromZone, card=Forest, fromZone=OUTSIDE
If you use the fast match button, your player name is always "Human".
So I guess if you change "cbt" to "Human" it will work.
User avatar
LevelX
DEVELOPER
 
Posts: 1677
Joined: 08 Dec 2011, 15:08
Has thanked: 174 times
Been thanked: 374 times

Re: Help implementing a card

Postby Backfir3 » 23 Sep 2013, 19:11

I need help with Lotus Vale. I've done the card and the part that's bugged is that when the player doesn't sacrifice the lands Lotus Vale should go to the graveyard, instead nothing happens. In server console I have no error. Help :?

Here's the code

Code: Select all
package mage.sets.weatherlight;

import java.util.List;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.effects.ReplacementEffectImpl;
import mage.abilities.effects.common.AddManaOfAnyColorEffect;
import mage.abilities.mana.SimpleManaAbility;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.choices.ChoiceColor;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.filter.common.FilterLandPermanent;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.permanent.TappedPredicate;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.ZoneChangeEvent;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetControlledPermanent;

/**
 *
 * @author Backfir3
 */
public class LotusVale extends CardImpl<LotusVale> {

    public LotusVale(UUID ownerId) {
        super(ownerId, 165, "Lotus Vale", Rarity.RARE, new CardType[]{CardType.LAND}, "");
        this.expansionSetCode = "WTH";

      // If Lotus Vale would enter the battlefield, sacrifice two untapped lands instead.
      // If you do, put Lotus Vale onto the battlefield. If you don't, put it into its owner's graveyard.
        this.addAbility(new SimpleStaticAbility(Zone.ALL, new LotusValeReplacementEffect()));
      
      // {T}: Add three mana of any one color to your mana pool.
        Ability ability = new SimpleManaAbility(Zone.BATTLEFIELD, new AddManaOfAnyColorEffect(3), new TapSourceCost());
        ability.addChoice(new ChoiceColor());
        this.addAbility(ability);
    }

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

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

class LotusValeReplacementEffect extends ReplacementEffectImpl<LotusValeReplacementEffect> {

    private static final FilterLandPermanent filter = new FilterLandPermanent("two untapped lands");

    static {
        filter.add(Predicates.not(new TappedPredicate()));
    }

    public LotusValeReplacementEffect() {
        super(Duration.WhileOnBattlefield, Outcome.Exile);
        staticText = "If Lotus Vale would enter the battlefield, sacrifice two untapped lands instead. If you do, put Lotus Vale onto the battlefield. If you don't, put it into its owner's graveyard.";
    }

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

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

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

    @Override
    public boolean replaceEvent(GameEvent event, Ability source, Game game) {
        Player player = game.getPlayer(source.getControllerId());
      TargetControlledPermanent target = new TargetControlledPermanent(2, 2, filter, false);
        if (player != null){
            if (player.chooseUse(Outcome.Sacrifice, "Sacrifice two untapped lands or Lotus Vale goes to the owner's graveyard?", game)) {
                if (target.canChoose(player.getId(), game)) {
                    while (!target.isChosen()) {
                        player.choose(Outcome.Sacrifice, target, source.getSourceId(), game);
                    }
                    List<UUID> chosenTargets = target.getTargets();
               for (UUID permID : chosenTargets) {
                  Permanent permanent = game.getPermanent(permID);
                  if (permanent != null) {
                     if (!permanent.sacrifice(source.getSourceId(), game)) {
                                return true;
                            }
                  }
               }
               return false;
                }
            }
            else{
                Card card = game.getCard(event.getTargetId());
                if (card != null) {
                    return card.moveToZone(Zone.GRAVEYARD, source.getId(), game, true);
                }
                return true;
            }
           
        }
        return false;
    }

    @Override
    public boolean applies(GameEvent event, Ability source, Game game) {
        if (event.getType() == GameEvent.EventType.ZONE_CHANGE && ((ZoneChangeEvent)event).getToZone() == Zone.BATTLEFIELD) {
            UUID sourceID = source.getSourceId();
            if(source.getSourceId().equals(event.getTargetId())){
                return true;
            }
        }
        return false;
    }

}
Btw, when I was looking for a similar card, I discovered Mox Diamond and it's bugged too. When the player chose not to discard a land, Mox Diamond clones itself, one copy in the graveyard and another on the battlefield. In console there's this "FATAL [2013-09-23 20:54 [01:692]] CardImpl[pool-3-thread-1]: invalid zone for card - BATTLEFIELD".
Backfir3
 
Posts: 7
Joined: 20 Jan 2012, 18:02
Has thanked: 1 time
Been thanked: 2 times

Re: Help implementing a card

Postby LevelX » 23 Sep 2013, 22:13

Backfir3 wrote:I need help with Lotus Vale. I've done the card and the part that's bugged is that when the player doesn't sacrifice the lands Lotus Vale should go to the graveyard, instead nothing happens. In server console I have no error. Help :?
Btw, when I was looking for a similar card, I discovered Mox Diamond and it's bugged too. When the player chose not to discard a land, Mox Diamond clones itself, one copy in the graveyard and another on the battlefield. In console there's this "FATAL [2013-09-23 20:54 [01:692]] CardImpl[pool-3-thread-1]: invalid zone for card - BATTLEFIELD".
Hello Backfir3,
I fixed Mox Diamon (used the wrong event), I guess you can change Lotus Vale in the same way.
Regards
LevelX2
User avatar
LevelX
DEVELOPER
 
Posts: 1677
Joined: 08 Dec 2011, 15:08
Has thanked: 174 times
Been thanked: 374 times

Re: Help implementing a card

Postby cbt33 » 10 Oct 2013, 19:08

Trying to implement Cabal Patriarch I receive a null pointer exception with this:

Code: Select all
public class CabalPatriarch extends CardImpl<CabalPatriarch> {

    public CabalPatriarch(UUID ownerId) {
        super(ownerId, 120, "Cabal Patriarch", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{3}{B}{B}{B}");
        this.expansionSetCode = "ODY";
        this.supertype.add("Legendary");
        this.subtype.add("Human");
        this.subtype.add("Wizard");

        this.color.setBlack(true);
        this.power = new MageInt(5);
        this.toughness = new MageInt(5);

       // {2}{B}, Sacrifice a creature: Target creature gets -2/-2 until end of turn.
      Ability ability1 = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostTargetEffect(-2, -2, Duration.EndOfTurn), new ManaCostsImpl("{2}{B}"));
      ability1.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(true), true));
      ability1.addTarget(new TargetCreaturePermanent(true));
      this.addAbility(ability1);
       
        // {2}{B}, Exile a creature card from your graveyard: Target creature gets -2/-2 until end of turn.
      Ability ability2 = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostTargetEffect(-2, -2, Duration.EndOfTurn), new ManaCostsImpl("{2}{B}"));
      ability2.addCost(new ExileFromGraveCost(new TargetCardInYourGraveyard(new FilterCreatureCard())));
      ability2.addTarget(new TargetCreaturePermanent(true));
      this.addAbility(ability2);
    }

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

    @Override
    public CabalPatriarch copy() {
        return new CabalPatriarch(this);
    }
}
Also, if I was given access to edit the main on the GitHub repo, should I still do a pull request for what I add just to make sure someone looks at it before it goes through?
cbt33
 
Posts: 11
Joined: 24 Aug 2012, 01:32
Has thanked: 3 times
Been thanked: 0 time

Re: Help implementing a card

Postby LevelX » 10 Oct 2013, 20:59

cbt33 wrote:Trying to implement Cabal Patriarch I receive a null pointer exception with this:

Code: Select all
 new SacrificeTargetCost(new TargetControlledCreaturePermanent(true), true);
The problem was the second parameter of the SacrificeTargetCost.


Here's the working code:
Code: Select all
public class CabalPatriarch extends CardImpl<CabalPatriarch> {

    public CabalPatriarch(UUID ownerId) {
        super(ownerId, 120, "Cabal Patriarch", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{3}{B}{B}{B}");
        this.expansionSetCode = "ODY";
        this.supertype.add("Legendary");
        this.subtype.add("Human");
        this.subtype.add("Wizard");

        this.color.setBlack(true);
        this.power = new MageInt(5);
        this.toughness = new MageInt(5);

       // {2}{B}, Sacrifice a creature: Target creature gets -2/-2 until end of turn.
      Ability ability1 = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostTargetEffect(-2, -2, Duration.EndOfTurn), new ManaCostsImpl("{2}{B}"));
      TargetControlledPermanent target = new TargetControlledPermanent(new FilterControlledCreaturePermanent(""));
      target.setRequired(true);
      ability1.addCost(new SacrificeTargetCost(target));
      ability1.addTarget(new TargetCreaturePermanent(true));
      this.addAbility(ability1);

        // {2}{B}, Exile a creature card from your graveyard: Target creature gets -2/-2 until end of turn.
      Ability ability2 = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostTargetEffect(-2, -2, Duration.EndOfTurn), new ManaCostsImpl("{2}{B}"));
      ability2.addCost(new ExileFromGraveCost(new TargetCardInYourGraveyard(new FilterCreatureCard("a creature card"))));
      ability2.addTarget(new TargetCreaturePermanent(true));
      this.addAbility(ability2);
    }

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

    @Override
    public CabalPatriarch copy() {
        return new CabalPatriarch(this);
    }
}
cbt33 wrote:Also, if I was given access to edit the main on the GitHub repo, should I still do a pull request for what I add just to make sure someone looks at it before it goes through?
If you like or not sure if your code is ok, you can do a pull request.
User avatar
LevelX
DEVELOPER
 
Posts: 1677
Joined: 08 Dec 2011, 15:08
Has thanked: 174 times
Been thanked: 374 times

Re: Help implementing a card

Postby cbt33 » 21 Dec 2013, 04:07

If I commit files using NetBeans>Team>Commit... do they show up in or around the main repo if I have a cloned repo or are there more steps?
cbt33
 
Posts: 11
Joined: 24 Aug 2012, 01:32
Has thanked: 3 times
Been thanked: 0 time

Re: Help implementing a card

Postby LevelX » 21 Dec 2013, 14:34

cbt33 wrote:If I commit files using NetBeans>Team>Commit... do they show up in or around the main repo if I have a cloned repo or are there more steps?
You have also to do [Project]->Git->Remote->Push... after committing to your local repository.
User avatar
LevelX
DEVELOPER
 
Posts: 1677
Joined: 08 Dec 2011, 15:08
Has thanked: 174 times
Been thanked: 374 times

Re: Help implementing a card

Postby cbt33 » 03 Jan 2014, 01:45

Can anyone tell why the tool tip for Zombie Cannibal doesn't show and the tooltip for Savage Firecat doesn't show completely?

Zombie Cannibal:
Code: Select all
      this.power = new MageInt(1);
        this.toughness = new MageInt(1);

        // Whenever Zombie Cannibal deals combat damage to a player, you may exile target card from that player's graveyard.
    this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new ZombieCannibalEffect(), true, true));
   
    }

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

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

class ZombieCannibalEffect extends OneShotEffect<ZombieCannibalEffect> {
   
    public ZombieCannibalEffect() {
        super(Outcome.Exile);
        staticText = "you may exile target card from that player's graveyard.";
    }
   
    public ZombieCannibalEffect(final ZombieCannibalEffect effect) {
        super(effect);
    }
   
    @Override
    public ZombieCannibalEffect copy() {
        return new ZombieCannibalEffect(this);
    }
   
    @Override
    public boolean apply(Game game, Ability source) {
        FilterCard filter = new FilterCard();
        Player player = game.getPlayer(source.getTargets().getFirstTarget());
        if (player != null) {
            filter.add(new OwnerIdPredicate(player.getId()));
            Target target = new TargetCardInGraveyard(filter);
            game.getPermanent(target.getFirstTarget()).moveToExile(null, null, source.getSourceId(), game);
        }
        return false;
    }
   
}
Savage Firecat:
Code: Select all
this.addAbility(new SavageFirecatTriggeredAbility(new RemoveCounterSourceEffect(new PlusOneCounter(1))));

    }

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

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

class SavageFirecatTriggeredAbility extends TriggeredAbilityImpl<SavageFirecatTriggeredAbility> {

    public SavageFirecatTriggeredAbility(Effect effect) {
        super(Zone.BATTLEFIELD, effect, false);
    }

    public SavageFirecatTriggeredAbility(final SavageFirecatTriggeredAbility ability) {
        super(ability);
    }

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

    @Override
    public boolean checkTrigger(GameEvent event, Game game) {
        if (event.getType() == EventType.TAPPED_FOR_MANA &&
                game.getCard(event.getSourceId()).getCardType().contains(CardType.LAND) &&
                event.getPlayerId().equals(this.controllerId)){
            return true;
        }
    return false;
}
   
    @Override
    public String getRule() {
        return "Whenever you tap a land for mana,";
}

}
cbt33
 
Posts: 11
Joined: 24 Aug 2012, 01:32
Has thanked: 3 times
Been thanked: 0 time

Re: Help implementing a card

Postby LevelX » 03 Jan 2014, 06:47

cbt33 wrote:Can anyone tell why the tool tip for Zombie Cannibal doesn't show and the tooltip for Savage Firecat doesn't show completely?

Zombie Cannibal:
Code: Select all
      this.power = new MageInt(1);
        this.toughness = new MageInt(1);

        // Whenever Zombie Cannibal deals combat damage to a player, you may exile target card from that player's graveyard.
    this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new ZombieCannibalEffect(), true, true));
   
    }

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

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

class ZombieCannibalEffect extends OneShotEffect<ZombieCannibalEffect> {
   
    public ZombieCannibalEffect() {
        super(Outcome.Exile);
        staticText = "you may exile target card from that player's graveyard.";
    }
   
    public ZombieCannibalEffect(final ZombieCannibalEffect effect) {
        super(effect);
    }
   
    @Override
    public ZombieCannibalEffect copy() {
        return new ZombieCannibalEffect(this);
    }
   
    @Override
    public boolean apply(Game game, Ability source) {
        FilterCard filter = new FilterCard();
        Player player = game.getPlayer(source.getTargets().getFirstTarget());
        if (player != null) {
            filter.add(new OwnerIdPredicate(player.getId()));
            Target target = new TargetCardInGraveyard(filter);
            game.getPermanent(target.getFirstTarget()).moveToExile(null, null, source.getSourceId(), game);
        }
        return false;
    }
   
}
Savage Firecat:
Code: Select all
this.addAbility(new SavageFirecatTriggeredAbility(new RemoveCounterSourceEffect(new PlusOneCounter(1))));

    }

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

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

class SavageFirecatTriggeredAbility extends TriggeredAbilityImpl<SavageFirecatTriggeredAbility> {

    public SavageFirecatTriggeredAbility(Effect effect) {
        super(Zone.BATTLEFIELD, effect, false);
    }

    public SavageFirecatTriggeredAbility(final SavageFirecatTriggeredAbility ability) {
        super(ability);
    }

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

    @Override
    public boolean checkTrigger(GameEvent event, Game game) {
        if (event.getType() == EventType.TAPPED_FOR_MANA &&
                game.getCard(event.getSourceId()).getCardType().contains(CardType.LAND) &&
                event.getPlayerId().equals(this.controllerId)){
            return true;
        }
    return false;
}
   
    @Override
    public String getRule() {
        return "Whenever you tap a land for mana,";
}

}
Did you delete the cards.db files of the server and client project after making changes to the cards?
Because the texts are taken from there won't be updated automatically! Only if you delete the files, then they are recreated with the updated texts from the changed java sources.
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 2 guests

Main Menu

User Menu

Our Partners


Who is online

In total there are 2 users online :: 0 registered, 0 hidden and 2 guests (based on users active over the past 10 minutes)
Most users ever online was 9298 on 10 Oct 2025, 12:54

Users browsing this forum: No registered users and 2 guests

Login Form