Help implementing a card
Moderators: North, BetaSteward, noxx, jeffwadsworth, JayDi, TheElk801, LevelX, CCGHQ Admins
Help implementing a card
by Rafbill » 29 Sep 2011, 16:46
I started trying to implement some cards for Mage, which is the more advanced project i have seen so far.
But i couldn't manage to implement the "attacking" part of the rules in this card :
http://magiccards.info/mt/en/20.html
Here is the class (without imports and license):
No method in class Combat seems to be relevant, I'll try adding one (this card is the only card with an effect of that kind)
EDIT : Implemented it, added a method, "If you use the ability, you choose which player or planeswalker the Soldier creature is attacking. It doesn't have to attack the same player or planeswalker as Preeminent Captain." is still not implemented.
But i couldn't manage to implement the "attacking" part of the rules in this card :
http://magiccards.info/mt/en/20.html
Here is the class (without imports and license):
- Code: Select all
public class PreeminentCaptain extends CardImpl<PreeminentCaptain> {
final PreeminentCaptainEffect effect = new PreeminentCaptainEffect();
public PreeminentCaptain(UUID ownerId) {
super(ownerId, 20, "Preeminent Captain", Rarity.RARE,
new CardType[] { CardType.CREATURE }, "{2}{W}");
this.expansionSetCode = "MOR";
this.subtype.add("Kithkin");
this.subtype.add("Soldier");
this.color.setWhite(true);
this.power = new MageInt(2);
this.toughness = new MageInt(2);
this.addAbility(FirstStrikeAbility.getInstance());
// Whenever Preeminent Captain attacks, you may put a Soldier creature
// card from your hand onto the battlefield tapped and attacking.
this.addAbility(new AttacksTriggeredAbility(effect, true));
}
public PreeminentCaptain(final PreeminentCaptain card) {
super(card);
}
@Override
public PreeminentCaptain copy() {
return new PreeminentCaptain(this);
}
}
class PreeminentCaptainEffect extends OneShotEffect<PreeminentCaptainEffect> {
protected TargetCardInHand target;
public PreeminentCaptainEffect() {
super(Outcome.PutCreatureInPlay);
target = new TargetCardInHand(new FilterSoldierCard());
}
public PreeminentCaptainEffect(final PreeminentCaptainEffect effect) {
super(effect);
target = effect.target;
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
if (target.choose(getOutcome(), player.getId(), game)) {
if (target.getTargets().size() > 0) {
UUID cardId = (UUID) target.getTargets().toArray()[0];
Card card = player.getHand().get(cardId, game);
if (card != null) {
if (card.putOntoBattlefield(game, Zone.HAND,
source.getId(), source.getControllerId())) {
Permanent permanent = game.getPermanent(card.getId());
permanent.setTapped(true);
// ? ? ?
}
}
return true;
}
}
return false;
}
@Override
public PreeminentCaptainEffect copy() {
return new PreeminentCaptainEffect(this);
}
}
class FilterSoldierCard extends FilterCard<FilterSoldierCard> {
public FilterSoldierCard() {
this("a soldier creature card.");
}
public FilterSoldierCard(String name) {
super(name);
cardType.add(CardType.CREATURE);
subtype.add("Soldier");
}
public FilterSoldierCard(final FilterSoldierCard filter) {
super(filter);
}
@Override
public FilterSoldierCard copy() {
return new FilterSoldierCard(this);
}
}
No method in class Combat seems to be relevant, I'll try adding one (this card is the only card with an effect of that kind)
EDIT : Implemented it, added a method, "If you use the ability, you choose which player or planeswalker the Soldier creature is attacking. It doesn't have to attack the same player or planeswalker as Preeminent Captain." is still not implemented.
- Rafbill
- Posts: 1
- Joined: 28 Sep 2011, 17:51
- Has thanked: 0 time
- Been thanked: 0 time
Re: Help implementing a card
by nantuko84 » 29 Sep 2011, 19:53
Hi, just add this line to you effect:
- Code: Select all
game.getCombat().declareAttacker(permanent.getId(), game.getCombat().getDefendingPlayer(source.getSourceId()), game);
Mage\MagicWars blog: http://mwars.blogspot.com/
Re: Help implementing a card
by jeffwadsworth » 20 Jun 2012, 02:59
Working on Living Destiny. I can not select a card from my hand with this code. Yes, it supposed to be a creature card, but it is just a test.
- 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.riseoftheeldrazi;
import java.util.UUID;
import mage.Constants;
import mage.Constants.CardType;
import mage.Constants.Rarity;
import mage.abilities.Ability;
import mage.abilities.costs.CostImpl;
import mage.abilities.effects.OneShotEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.Cards;
import mage.cards.CardsImpl;
import mage.filter.FilterCard;
import mage.filter.common.FilterCreatureCard;
import mage.game.Game;
import mage.players.Player;
import mage.target.common.TargetCardInHand;
/**
*
* @author jeffwadsworth
*/
public class LivingDestiny extends CardImpl<LivingDestiny> {
public LivingDestiny(UUID ownerId) {
super(ownerId, 195, "Living Destiny", Rarity.COMMON, new CardType[]{CardType.INSTANT}, "{3}{G}");
this.expansionSetCode = "ROE";
this.color.setGreen(true);
// As an additional cost to cast Living Destiny, reveal a creature card from your hand.
TargetCardInHand targetCard = new TargetCardInHand(new FilterCard("a card"));
this.getSpellAbility().addCost(new RevealTargetCost(targetCard));
// You gain life equal to the revealed card's converted mana cost.
this.getSpellAbility().addEffect(new LivingDestinyEffect());
}
public LivingDestiny(final LivingDestiny card) {
super(card);
}
@Override
public LivingDestiny copy() {
return new LivingDestiny(this);
}
}
class RevealTargetCost extends CostImpl<RevealTargetCost> {
protected int convertedManaCosts = 0;
public RevealTargetCost(TargetCardInHand target) {
this.addTarget(target);
this.text = "Reveal " + target.getTargetName();
}
public RevealTargetCost(RevealTargetCost cost) {
super(cost);
}
@Override
public boolean pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana) {
if (targets.choose(Constants.Outcome.Benefit, controllerId, sourceId, game)) {
Player player = game.getPlayer(controllerId);
Cards cards = new CardsImpl();
for (UUID targetId: targets.get(0).getTargets()) {
Card card = player.getHand().get(targetId, game);
if (card == null)
return false;
convertedManaCosts = card.getManaCost().convertedManaCost();
cards.add(card);
player.revealCards("Revealed card", cards, game);
return true;
}
}
return false;
}
public int getConvertedCosts() {
return convertedManaCosts;
}
@Override
public boolean canPay(UUID sourceId, UUID controllerId, Game game) {
return targets.canChoose(controllerId, game);
}
@Override
public RevealTargetCost copy() {
return new RevealTargetCost(this);
}
}
class LivingDestinyEffect extends OneShotEffect<LivingDestinyEffect> {
public LivingDestinyEffect() {
super(Constants.Outcome.GainLife);
staticText = "You gain life equal to its converted mana cost";
}
public LivingDestinyEffect(LivingDestinyEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
RevealTargetCost cost = (RevealTargetCost) source.getCosts().get(0);
if (cost != null) {
Player player = game.getPlayer(source.getControllerId());
int CMC = cost.convertedManaCosts;
if (player != null) {
player.gainLife(CMC, game);
}
}
return true;
}
@Override
public LivingDestinyEffect copy() {
return new LivingDestinyEffect(this);
}
}
- jeffwadsworth
- Super Tester Elite
- Posts: 1171
- Joined: 20 Oct 2010, 04:47
- Location: USA
- Has thanked: 287 times
- Been thanked: 69 times
Re: Help implementing a card
by jmartus » 20 Jun 2012, 04:01
one of my favorite cards thank you hope you get it working.
Re: Help implementing a card
by noxx » 20 Jun 2012, 07:30
You forgot to set "paid = true;" in RevealTargetCost after card was revealed.jeffwadsworth wrote:Working on Living Destiny. I can not select a card from my hand with this code. Yes, it supposed to be a creature card, but it is just a test.
I've commited 3 tests for your card, so you can use them to make sure that your implementation works.
Best Regards,
Noxx
Re: Help implementing a card
by jeffwadsworth » 03 Jul 2012, 02:22
Looking at Stasis. Considering we do not want to over-tax the system, is there a way to efficiently handle this card?
- jeffwadsworth
- Super Tester Elite
- Posts: 1171
- Joined: 20 Oct 2010, 04:47
- Location: USA
- Has thanked: 287 times
- Been thanked: 69 times
Re: Help implementing a card
by North » 03 Jul 2012, 12:09
Breeding Pit and Justice are for the first effect.
There is Yosei, the Morning Star who implements a similar behavior to the second effect.
There is Yosei, the Morning Star who implements a similar behavior to the second effect.
Re: Help implementing a card
by jeffwadsworth » 03 Jul 2012, 21:39
Yes, I noticed that and others, but that targets player and it is a one-time effect. I wish it was that simple.North wrote:Breeding Pit and Justice are for the first effect.
There is Yosei, the Morning Star who implements a similar behavior to the second effect.
- jeffwadsworth
- Super Tester Elite
- Posts: 1171
- Joined: 20 Oct 2010, 04:47
- Location: USA
- Has thanked: 287 times
- Been thanked: 69 times
Re: Help implementing a card
by jeffwadsworth » 04 Jul 2012, 15:56
Working on Pithing Needle. Does anyone know how to reference an AbilityType of an (GameEvent.EventType.Activate_Ability) event?
For this card, the activated ability of the chosen card does not hit the stack, so something like:
stackAbility.getAbilityType() != Constants.AbilityType.MANA
will not work. It needs to be able to check the ability type of the activated ability before it hits the stack.
For this card, the activated ability of the chosen card does not hit the stack, so something like:
stackAbility.getAbilityType() != Constants.AbilityType.MANA
will not work. It needs to be able to check the ability type of the activated ability before it hits the stack.
- jeffwadsworth
- Super Tester Elite
- Posts: 1171
- Joined: 20 Oct 2010, 04:47
- Location: USA
- Has thanked: 287 times
- Been thanked: 69 times
Re: Help implementing a card
by North » 04 Jul 2012, 17:37
I could try implementing Stasis if you want.
Also, did you try writing a replacement effect for Pithing Needle? Stony Silence abd Phyrexian Revoker have something similar for example. I don't know if I've hit the right spot.
Also, did you try writing a replacement effect for Pithing Needle? Stony Silence abd Phyrexian Revoker have something similar for example. I don't know if I've hit the right spot.
Re: Help implementing a card
by jeffwadsworth » 04 Jul 2012, 19:59
Please go ahead with the Stasis if you have it figured out. The code for Pithing Needle is a replacement effect, but that isn't the problem. It needs to check the "activate_ability" to see if it is a mana ability. Everything else is done and works fine.North wrote:I could try implementing Stasis if you want.
Also, did you try writing a replacement effect for Pithing Needle? Stony Silence abd Phyrexian Revoker have something similar for example. I don't know if I've hit the right spot.
Essentially, I am looking for something like:
Ability activatedAbility = game.getActivatedAbility(event.getSourceId());
That way we could check to see if it is a mana ability, etc.
activatedAbility.getAbilityType() != Constants.AbilityType.MANA
- jeffwadsworth
- Super Tester Elite
- Posts: 1171
- Joined: 20 Oct 2010, 04:47
- Location: USA
- Has thanked: 287 times
- Been thanked: 69 times
Re: Help implementing a card
by jeffwadsworth » 05 Jul 2012, 23:12
Nevermind about Pithing Needle. I found a solution.
- jeffwadsworth
- Super Tester Elite
- Posts: 1171
- Joined: 20 Oct 2010, 04:47
- Location: USA
- Has thanked: 287 times
- Been thanked: 69 times
Re: Help implementing a card
by jeffwadsworth » 07 Jul 2012, 19:40
Does anyone see the issue with this code for "Rhox Faithmender"? M13. The amount is changed in the event, but not applied during resolution. Weird.
http://gatherer.wizards.com/Pages/Card/ ... eid=279987
http://gatherer.wizards.com/Pages/Card/ ... eid=279987
- 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.magic2013;
import java.util.UUID;
import mage.Constants;
import mage.Constants.CardType;
import mage.Constants.Rarity;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.ReplacementEffectImpl;
import mage.abilities.keyword.LifelinkAbility;
import mage.cards.CardImpl;
import mage.game.Game;
import mage.game.events.GameEvent;
/**
*
* @author jeffwadsworth
*/
public class RhoxFaithmender extends CardImpl<RhoxFaithmender> {
public RhoxFaithmender(UUID ownerId) {
super(ownerId, 29, "Rhox Faithmender", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{3}{W}");
this.expansionSetCode = "M13";
this.subtype.add("Rhino");
this.subtype.add("Monk");
this.color.setWhite(true);
this.power = new MageInt(1);
this.toughness = new MageInt(5);
// Lifelink
this.addAbility(LifelinkAbility.getInstance());
// If you would gain life, you gain twice that much life instead.
this.addAbility(new SimpleStaticAbility(Constants.Zone.BATTLEFIELD, new RhoxFaithmenderEffect()));
}
public RhoxFaithmender(final RhoxFaithmender card) {
super(card);
}
@Override
public RhoxFaithmender copy() {
return new RhoxFaithmender(this);
}
}
class RhoxFaithmenderEffect extends ReplacementEffectImpl<RhoxFaithmenderEffect> {
public RhoxFaithmenderEffect() {
super(Constants.Duration.WhileOnBattlefield, Constants.Outcome.Benefit);
staticText = "If you would gain life, you gain twice that much life instead.";
}
public RhoxFaithmenderEffect(final RhoxFaithmenderEffect effect) {
super(effect);
}
@Override
public RhoxFaithmenderEffect copy() {
return new RhoxFaithmenderEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
return true;
}
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
return apply(game, source);
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
switch (event.getType()) {
case GAIN_LIFE:
if (event.getPlayerId().equals(source.getControllerId())) {
event.setAmount(event.getAmount() * 2);
}
}
return false;
}
}
- jeffwadsworth
- Super Tester Elite
- Posts: 1171
- Joined: 20 Oct 2010, 04:47
- Location: USA
- Has thanked: 287 times
- Been thanked: 69 times
Re: Help implementing a card
by jeffwadsworth » 08 Jul 2012, 06:40
Well, I thought I had a way to access the activated ability, but no dice. I will get back to it in time.
- jeffwadsworth
- Super Tester Elite
- Posts: 1171
- Joined: 20 Oct 2010, 04:47
- Location: USA
- Has thanked: 287 times
- Been thanked: 69 times
Who is online
Users browsing this forum: No registered users and 15 guests