It is currently 08 Sep 2025, 17:01
   
Text Size

Spike keyword

Post MTG Forge Related Programming Questions Here

Moderators: timmermac, Blacksmith, KrazyTheFox, Agetian, friarsol, CCGHQ Admins

Spike keyword

Postby Chris H. » 11 Aug 2010, 10:27

DennisBergkamp wrote:I noticed with the spike keyword that it doesn't seem to remove counters :)
The AI was "moving" +1/+1 counters from his Spike Weaver to his Elephant token, but the weaver wasn't actually losing them.
`
friarisol wrote:That cheater. It looks like I never changed the AI Targetting from the inherited stuff. And the Counter gets removed for the Human in selectCard, so it would need to happen in the chooseTargetAI code.

My local codebase is a mess right now if someone else wants to fix this up. I'll get to this when I can if noone else takes a whack at it.
`
I now have a canPlayAI(), chooseTargetAI() and getCreature() methods in place and have simplified the resolve() method. It looks like I still need to edit the input and want to do some StringBuilder work.

I am at an early stage at this moment and it is not yet ready to test.

Code: Select all
@Override
public boolean canPlayAI() {
    return getCreature().size() != 0
            && card.getCounters(Counters.P1P1) > 0
            && !CardFactoryUtil.AI_doesCreatureAttack(card);
}//canPlayAI()

@Override
public void chooseTargetAI() {
    Card best = CardFactoryUtil.AI_getBestCreature(getCreature());
    setTargetCard(best);
}//chooseTargetAI()

CardList getCreature() {
    CardList list = new CardList(AllZone.Computer_Play.getCards());
    list = list.filter(new CardListFilter() {
        public boolean addCard(Card c) {
            return c.isCreature()
                    && CardFactoryUtil.canTarget(card, c)
                    && c.getNetAttack() > card.getNetAttack()
                    && c != card;
        }
    });
    return list;
}//getCreature()

@Override
public void resolve() {
    if (AllZone.GameAction.isCardInPlay(getTargetCard())
            && CardFactoryUtil.canTarget(card, getTargetCard())) {
        card.subtractCounter(Counters.P1P1, 1);
        getTargetCard().addCounter(Counters.P1P1, 1);
    }
}//resolve()
User avatar
Chris H.
Forge Moderator
 
Posts: 6320
Joined: 04 Nov 2008, 12:11
Location: Mac OS X Yosemite
Has thanked: 644 times
Been thanked: 643 times

Re: Spike keyword

Postby Chris H. » 11 Aug 2010, 12:58

I think that I have finished Sol's spike keyword. I think that I now understand that we:

1 pay mana
2 choose target & remove counter
3 add counter

I will now merge this version into the SVN:

Code: Select all
        int spike = hasKeyword(card, "Spike");
        if(spike != -1) {
            String parse = card.getKeyword().get(spike).toString();
            card.removeIntrinsicKeyword(parse);
           
            final int m = Integer.parseInt(parse.substring(6));
            String t = card.getSpellText();
            if(!t.equals("")) t += "\r\n";
            card.setText(t
                    + parse
                    + " (This enters the battlefield with "
                    + m
                    + " +1/+1 counters on it.)");
           
            card.addComesIntoPlayCommand(new Command() {
                private static final long serialVersionUID = -2292898970576123040L;

                public void execute() {
                    card.addCounter(Counters.P1P1, m);
                }
            });//ComesIntoPlayCommand
           
            final SpellAbility ability = new Ability(card, "2") {
               
                @Override
                public boolean canPlay() {
                    // stack peek is needed to prevent Spike Feeder from trying to double activate
                    SpellAbility sa;
                    for (int i = 0; i < AllZone.Stack.size(); i++) {
                        sa = AllZone.Stack.peek(i);
                        if (sa.getSourceCard().equals(card)) return false;
                    }
                    return (card.getCounters(Counters.P1P1) > 0);
                }//canPlay()
               
                @Override
                public boolean canPlayAI() {
                    return getCreature().size() != 0
                            && card.getCounters(Counters.P1P1) > 0
                            && !CardFactoryUtil.AI_doesCreatureAttack(card);
                }//canPlayAI()
               
                @Override
                public void chooseTargetAI() {
                    Card best = CardFactoryUtil.AI_getBestCreature(getCreature());
                    setTargetCard(best);
                    card.subtractCounter(Counters.P1P1, 1);
                }//chooseTargetAI()
               
                CardList getCreature() {
                    CardList list = new CardList(AllZone.Computer_Play.getCards());
                    list = list.filter(new CardListFilter() {
                        public boolean addCard(Card c) {
                            return c.isCreature()
                                    && CardFactoryUtil.canTarget(card, c)
                                    && c.getNetAttack() > card.getNetAttack()
                                    && c != card;
                        }
                    });
                    return list;
                }//getCreature()
               
                @Override
                public void resolve() {
                    if (AllZone.GameAction.isCardInPlay(getTargetCard())
                            && CardFactoryUtil.canTarget(card, getTargetCard())) {
                        getTargetCard().addCounter(Counters.P1P1, 1);
                    }
                }//resolve()
            };//SpellAbility
           
            Input target = new Input() {
                private static final long serialVersionUID = 903928778649052032L;

                @Override
                public void showMessage() {
                    AllZone.Display.showMessage("Select target creature for " + card.getName());
                    ButtonUtil.enableOnlyCancel();
                }
               
                @Override
                public void selectButtonCancel() {
                    stop();
                }
               
                @Override
                public void selectCard(Card target, PlayerZone zone) {
                    // Choose a legal target, then remove a counter
                    if (!CardFactoryUtil.canTarget(ability, target)) {
                        AllZone.Display.showMessage("Cannot target this card (Shroud? Protection?).");
                    } else if (target.isCreature() && zone.is(Constant.Zone.Play)) {
                        card.subtractCounter(Counters.P1P1, 1);
                        ability.setTargetCard(target);
                        AllZone.Stack.add(ability);
                        AllZone.GameAction.checkStateEffects();
                        stop();
                    }
                }//selectCard()
            };//Input()
           
            ability.setAfterPayMana(target);
            StringBuffer sb = new StringBuffer();
            sb.append("Put a +1/+1 counter from ").append(card.getName()).append(" on target creature.");
            ability.setStackDescription(sb.toString());
            ability.setDescription("2, Remove a +1/+1 counter: Add a +1/+1 counter to target creature");
            card.addSpellAbility(ability);
        } // if Spike
User avatar
Chris H.
Forge Moderator
 
Posts: 6320
Joined: 04 Nov 2008, 12:11
Location: Mac OS X Yosemite
Has thanked: 644 times
Been thanked: 643 times


Return to Developer's Corner

Who is online

Users browsing this forum: No registered users and 46 guests

Main Menu

User Menu

Our Partners


Who is online

In total there are 46 users online :: 0 registered, 0 hidden and 46 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 46 guests

Login Form