It is currently 23 Apr 2024, 07:21
   
Text Size

Adding new cards with Groovy

Moderators: ubeefx, beholder, melvin, ShawnieBoy, Lodici, CCGHQ Admins

Adding new cards with Groovy

Postby melvin » 13 May 2013, 14:32

This is a new series of posts to show how easy it is to add new cards to Magarena. The files listed can be dropped into your Magarena/scripts folder and used right away. Interested to see more examples? Just look at the files in your Magarena/scripts folder.

We begin with two cards that have similar characteristic defining abilities. The card metadata (*.txt) was submitted by Aunukia to our mailing list. The groovy script added later to complete the card.

Image

Reckless One.txt
Code: Select all
name=Reckless One
url=http://magiccards.info/evg/en/48.html
image=http://magiccards.info/scans/en/evg/48.jpg
value=3.909
rarity=U
type=Creature
subtype=Goblin,Avatar
cost={3}{R}
ability=haste
timing=fmain
requires_groovy_code
Reckless_One.groovy
Code: Select all
[
    new MagicCDA() {
        @Override
        public void modPowerToughness(final MagicGame game,final MagicPlayer player,final MagicPowerToughness pt) {
            final int amount =
                player.getNrOfPermanentsWithSubType(MagicSubType.Goblin) +
                player.getOpponent().getNrOfPermanentsWithSubType(MagicSubType.Goblin);
            pt.set(amount,amount);
        }
    }
]
Image

Soulless_One.txt
Code: Select all
name=Soulless One
url=http://magiccards.info/pch/en/41.html
image=http://magiccards.info/scans/en/pch/41.jpg
value=4.329
rarity=U
type=Creature
subtype=Zombie,Avatar
cost={3}{B}
timing=main
requires_groovy_code
Soulless_One.groovy
Code: Select all
[
    new MagicCDA() {
        @Override
        public void modPowerToughness(final MagicGame game,final MagicPlayer player,final MagicPowerToughness pt) {
            final int battlefield =
                player.getNrOfPermanentsWithSubType(MagicSubType.Zombie) +
                player.getOpponent().getNrOfPermanentsWithSubType(MagicSubType.Zombie);
            final int graveyard =
                game.filterCards(player,MagicTargetFilter.TARGET_ZOMBIE_CARD_FROM_GRAVEYARD).size() +
                game.filterCards(player.getOpponent(),MagicTargetFilter.TARGET_ZOMBIE_CARD_FROM_GRAVEYARD).size();
            final int amount = battlefield + graveyard;
            pt.set(amount,amount);
        }
    }
]
User avatar
melvin
AI Programmer
 
Posts: 1062
Joined: 21 Mar 2010, 12:26
Location: Singapore
Has thanked: 36 times
Been thanked: 459 times

Re: Adding new cards with Groovy

Postby jeffwadsworth » 13 May 2013, 21:31

It definitely is getting closer to natural language scripting. Very clean.
jeffwadsworth
Super Tester Elite
 
Posts: 1171
Joined: 20 Oct 2010, 04:47
Location: USA
Has thanked: 287 times
Been thanked: 69 times

Re: Adding new cards with Groovy

Postby melvin » 14 May 2013, 06:33

jeffwadsworth wrote:It definitely is getting closer to natural language scripting. Very clean.
Thanks for the encouragement, we still got long ways to go to minimize the boilerplate in the script. On another front, we are also working on direct rules text parsing. Though the parsing part is going well, we are stuck at the implementation of an "interpreter".

Next card in this series is Scornful Æther-Lich. Card metadata was submitted by Aunukia via our mailing list.

Image
Scornful_AEther_Lich.txt
Code: Select all
name=Scornful AEther-Lich
url=http://magiccards.info/cfx/en/34.html
image=http://magiccards.info/scans/en/cfx/34.jpg
value=2.973
rarity=U
type=Artifact,Creature
subtype=Zombie,Wizard
cost={3}{U}
pt=2/4
timing=main
requires_groovy_code
Scornful_AEther_Lich.groovy
Code: Select all
[
    new MagicPermanentActivation(
        [MagicConditionFactory.ManaCost("{W}{B}")],
        new MagicActivationHints(MagicTiming.Main),
        "Gains") {

        @Override
        public MagicEvent[] getCostEvent(final MagicPermanent source) {
            return [
                new MagicPayManaCostEvent(
                    source,
                    source.getController(),
                    MagicManaCost.create("{W}{B}")
                )
            ];
        }

        @Override
        public MagicEvent getPermanentEvent(final MagicPermanent source, final MagicPayedCost payedCost) {
            return new MagicEvent(
                source,
                this,
                "SN gains fear and vigilance until end of turn."
            );
        }

        @Override
        public void executeEvent(final MagicGame game, final MagicEvent event) {
            game.doAction(new MagicSetAbilityAction(
                event.getPermanent(),
                [MagicAbility.Fear, MagicAbility.Vigilance]
            ));
        }
    }
]
User avatar
melvin
AI Programmer
 
Posts: 1062
Joined: 21 Mar 2010, 12:26
Location: Singapore
Has thanked: 36 times
Been thanked: 459 times

Re: Adding new cards with Groovy

Postby melvin » 15 May 2013, 14:09

What's the trick to implementing abilities of new cards? Find a similar card that is already in the game.

Today's card is Rotlung Reanimator from Onslaught. Its ability is similar to that of Requiem Angel, so we start of with Magarena/scripts/Requiem_Angel.groovy as the starting point, then modify the trigger's condition and effect until we get the new ability.

Image

Magarena/scripts/Rotlung_Reanimator.txt
Code: Select all
name=Rotlung Reanimator
url=http://magiccards.info/on/en/164.html
image=http://magiccards.info/scans/en/on/164.jpg
value=4.240
rarity=R
type=Creature
subtype=Zombie,Cleric
cost={2}{B}
pt=2/2
timing=main
requires_groovy_code
Magarena/scripts/Rotlung_Reanimator.groovy
Code: Select all
[
    new MagicWhenOtherPutIntoGraveyardFromPlayTrigger() {
        @Override
        public MagicEvent executeTrigger(final MagicGame game, final MagicPermanent permanent, final MagicPermanent diedPermanent) {
            return (permanent == diedPermanent || diedPermanent.hasSubType(MagicSubType.Cleric)) ?
                new MagicEvent(
                    permanent,
                    this,
                    "PN puts a 2/2 black Zombie creature token onto the battlefield."
                ):
                MagicEvent.NONE;
        }
        @Override
        public void executeEvent(
                final MagicGame game,
                final MagicEvent event) {
            game.doAction(new MagicPlayTokenAction(
                event.getPlayer(),
                TokenCardDefinitions.get("Zombie")
            ));
        }
    }
]
User avatar
melvin
AI Programmer
 
Posts: 1062
Joined: 21 Mar 2010, 12:26
Location: Singapore
Has thanked: 36 times
Been thanked: 459 times

Re: Adding new cards with Groovy

Postby melvin » 16 May 2013, 12:47

Today's card is Knight of the Skyward Eye. Luckly Magarena already has a card, Darkthicket Wolf, that has a very similar ability, we modify that to get the groovy script for our Knight.

Image

Magarena/scripts/Knight_of_the_Skyward_Eye.txt
Code: Select all
name=Knight of the Skyward Eye
url=http://magiccards.info/ala/en/15.html
image=http://magiccards.info/scans/en/ala/15.jpg
value=3.217
rarity=C
type=Creature
subtype=Human,Knight
cost={1}{W}
pt=2/2
timing=main
requires_groovy_code
Magarena/scripts/Knight_of_the_Skyward_Eye.groovy
Code: Select all
[
    new MagicPermanentActivation(
        [
            MagicCondition.ABILITY_ONCE_CONDITION,
            MagicConditionFactory.ManaCost("{3}{G}")
        ],
        new MagicActivationHints(MagicTiming.Pump),
        "Pump") {
        @Override
        public MagicEvent[] getCostEvent(final MagicPermanent source) {
            return [
                new MagicPayManaCostEvent(source,source.getController(),MagicManaCost.create("{3}{G}")),
                new MagicPlayAbilityEvent(source)
            ];
        }
        @Override
        public MagicEvent getPermanentEvent(final MagicPermanent source,final MagicPayedCost payedCost) {
            return new MagicEvent(
                source,
                this,
                "SN gets +3/+3 until end of turn."
            );
        }
        @Override
        public void executeEvent(final MagicGame game, final MagicEvent event) {
            game.doAction(new MagicChangeTurnPTAction(event.getPermanent(),3,3));
        }
    }
]
User avatar
melvin
AI Programmer
 
Posts: 1062
Joined: 21 Mar 2010, 12:26
Location: Singapore
Has thanked: 36 times
Been thanked: 459 times

Re: Adding new cards with Groovy

Postby melvin » 08 Jun 2013, 08:42

Been working on converting the rest of the cards to groovy script. It is finally done! For the June release, all cards will be using the groovy script.

Here is a very powerful card that was just added for the June release. Voice of Resurgence.

Image

scripts/Voice_of_Resurgence.txt
Code: Select all
name=Voice of Resurgence
url=http://magiccards.info/dgm/en/114.html
image=http://magiccards.info/scans/en/dgm/114.jpg
value=1.971
rarity=M
type=Creature
subtype=Elemental
cost={G}{W}
pt=2/2
timing=main
requires_groovy_code
scripts/Voice_of_Resurgence.groovy
Code: Select all
def WhenDies = new MagicWhenDiesTrigger() {
    @Override
    public MagicEvent getEvent(final MagicPermanent permanent) {
        return new MagicEvent(
            permanent,
            this,
            "PN puts a green and white Elemental creature token onto the battlefield with " +
            "\"This creature's power and toughness are each equal to the number of creatures you control.\""
        );
    }
    @Override
    public void executeEvent(final MagicGame game, final MagicEvent event) {
        game.doAction(new MagicPlayTokenAction(event.getPlayer(), TokenCardDefinitions.get("GW Elemental")));
    }
}

[
    WhenDies,
    new MagicWhenOtherSpellIsCastTrigger() {
        @Override
        public MagicEvent executeTrigger(final MagicGame game,final MagicPermanent permanent,final MagicCardOnStack cardOnStack) {
            return permanent.isEnemy(cardOnStack) && permanent.isController(game.getTurnPlayer()) ?
                WhenDies.getEvent(permanent) : MagicEvent.NONE;
        }
    }
]
The power of this card lies in the tokens it creates. Here is how it is scripted. We make use of the characteristic defining ability from Scion of the Wild so there is no new groovy code.

scripts/GW_Elemental.txt
Code: Select all
name=GW Elemental
token=Elemental
image=http://magiccards.info/extras/token/dragons-maze/elemental.jpg
value=3
type=Creature
subtype=Elemental
color=gw
cost={0}
requires_groovy_code=Scion of the Wild
User avatar
melvin
AI Programmer
 
Posts: 1062
Joined: 21 Mar 2010, 12:26
Location: Singapore
Has thanked: 36 times
Been thanked: 459 times

Re: Adding new cards with Groovy

Postby Huggybaby » 10 Jun 2013, 04:53

Congrats on the groovy milestone melvin!
User avatar
Huggybaby
Administrator
 
Posts: 3207
Joined: 15 Jan 2006, 19:44
Location: Finally out of Atlanta
Has thanked: 701 times
Been thanked: 594 times

Re: Adding new cards with Groovy

Postby melvin » 16 Jun 2013, 05:59

Huggybaby wrote:Congrats on the groovy milestone melvin!
Thanks for the encouragement, Huggybaby :D

It is great to see the number of compiled files go down to ~600 and all card code is done as Groovy scripts. This means it will be even easier to see how existing cards are implemented and extend it for new cards.

Another important system is now in the core engine, support for additional costs. We've had kicker and buyback costs but the current implementation is a little clunky and doesn't quite follow the game rules. The new additional cost system should hopefully allow us to implement kicker and buyback in a more natural way.

For now, let me present you with the first card that uses the additional cost system.

Image

Magarena/scripts/Goblin_Grenade.txt
Code: Select all
name=Goblin Grenade
url=http://magiccards.info/m12/en/140.html
image=http://magiccards.info/scans/en/m12/140.jpg
value=4.578
rarity=U
type=Sorcery
cost={R}
timing=removal
removal=5
requires_groovy_code
Note that the card script will only work with the upcoming June (1.39) release as it uses the new additional cost system.

Magarena/scripts/Goblin_Grenade.groovy
Code: Select all
[
    new MagicAdditionalCost() {
        @Override
        public MagicEvent getEvent(final MagicSource source) {
            return new MagicSacrificePermanentEvent(source, MagicTargetChoice.SACRIFICE_GOBLIN);   
        }
    },
    new MagicSpellCardEvent() {
        @Override
        public MagicEvent getEvent(final MagicCardOnStack cardOnStack,final MagicPayedCost payedCost) {
            return new MagicEvent(
                cardOnStack,
                MagicTargetChoice.NEG_TARGET_CREATURE_OR_PLAYER,
                new MagicDamageTargetPicker(5),
                this,
                "SN deals 5 damage to target creature or player\$."
            );
        }
        @Override
        public void executeEvent(final MagicGame game, final MagicEvent event) {
            event.processTarget(game,new MagicTargetAction() {
                public void doAction(final MagicTarget target) {
                    final MagicDamage damage=new MagicDamage(event.getSource(),target,5);
                    game.doAction(new MagicDealDamageAction(damage));
                }
            });
        }
    }
]
User avatar
melvin
AI Programmer
 
Posts: 1062
Joined: 21 Mar 2010, 12:26
Location: Singapore
Has thanked: 36 times
Been thanked: 459 times

Re: Adding new cards with Groovy

Postby melvin » 22 Jun 2013, 13:46

All cards with additional costs have been converted to use the new system, it is cleaner and closer to the way the rules work. Previously kicker (and similar mechanics such as buyback) was implemented by changing the target selection to include the kicker decision. Now it is done when paying the cost of an spell, after paying the mana cost.

The card of the day is

Image

Magarena/scripts/Death_Mutation.txt
Code: Select all
name=Death Mutation
url=http://magiccards.info/cmd/en/192.html
image=http://magiccards.info/scans/en/cmd/192.jpg
value=3.135
rarity=U
type=Sorcery
cost={6}{B}{G}
timing=removal
removal=4
requires_groovy_code
Magarena/scripts/Death_Mutation.groovy
Code: Select all
[
    new MagicSpellCardEvent() {
        @Override
        public MagicEvent getEvent(final MagicCardOnStack cardOnStack,final MagicPayedCost payedCost) {
            return new MagicEvent(
                cardOnStack,
                MagicTargetChoice.NEG_TARGET_NONBLACK_CREATURE,
                new MagicDestroyTargetPicker(true),
                this,
                "Destroy target nonblack creature\$. " +
                "It can't be regenerated. " +
                "Put X 1/1 green Saproling creature tokens onto the battlefield, where X is that creature's converted mana cost."
            );
        }
        @Override
        public void executeEvent(final MagicGame game, final MagicEvent event) {
            event.processTargetPermanent(game,new MagicPermanentAction() {
                public void doAction(final MagicPermanent creature) {
                    game.doAction(MagicChangeStateAction.Set(creature,MagicPermanentState.CannotBeRegenerated));
                    game.doAction(new MagicDestroyAction(creature));
                    game.doAction(new MagicPlayTokensAction(
                        event.getPlayer(),
                        TokenCardDefinitions.get("Saproling"),
                        creature.getConvertedCost()
                    ));
                }
            });
        }
    }
]
User avatar
melvin
AI Programmer
 
Posts: 1062
Joined: 21 Mar 2010, 12:26
Location: Singapore
Has thanked: 36 times
Been thanked: 459 times

Re: Adding new cards with Groovy

Postby melvin » 23 Jun 2013, 03:31

Was watching GP Las Vegas live and kept hearing about Oona. Decided to implement Oona for today to commemorate the largest GP in Magic history.

Image

Magarena/scripts/Oona__Queen_of_the_Fae.txt
Code: Select all
name=Oona, Queen of the Fae
url=http://magiccards.info/shm/en/172.html
image=http://magiccards.info/scans/en/shm/172.jpg
value=3.675
ability=flying
rarity=R
type=Legendary,Creature
subtype=Faerie,Wizard
cost={3}{U/B}{U/B}{U/B}
pt=5/5
timing=main
requires_groovy_code
Magarena/scripts/Oona__Queen_of_the_Fae.groovy
Code: Select all
[
    new MagicPermanentActivation(
        new MagicActivationHints(MagicTiming.Token),
        "Token"
    ) {
       
        @Override
        public MagicEvent[] getCostEvent(final MagicPermanent source) {
            return [new MagicPayManaCostEvent(source, "{X}{U/B}")];
        }

        @Override
        public MagicEvent getPermanentEvent(final MagicPermanent source,final MagicPayedCost payedCost) {
            return new MagicEvent(
                source,
                MagicTargetChoice.TARGET_OPPONENT,
                payedCost.getX(),
                this,
                "Choose a color. Target opponent\$ exiles the top RN cards of his or her library. " +
                "For each card of the chosen color exiled this way, put a 1/1 blue and black Faerie Rogue creature token with flying onto the battlefield."
            );
        }

        @Override
        public void executeEvent(final MagicGame outerGame, final MagicEvent outerEvent) {
            outerEvent.processTargetPlayer(outerGame,new MagicPlayerAction() {
                public void doAction(final MagicPlayer outerPlayer) {
                    outerGame.addEvent(new MagicEvent(
                        outerEvent.getSource(),
                        MagicColorChoice.ALL_INSTANCE,
                        outerPlayer,
                        {
                            final MagicGame game, final MagicEvent event ->
                            final MagicColor color = event.getChosenColor();
                            final MagicPlayer player = event.getRefPlayer();
                            final int x = outerEvent.getRefInt();
                            for (int i = 0; i < x && player.getLibrary().getCardAtTop() != MagicCard.NONE; i++) {
                                final MagicCard card = player.getLibrary().getCardAtTop();
                                game.doAction(new MagicRemoveCardAction(card,MagicLocationType.OwnersLibrary));
                                game.doAction(new MagicMoveCardAction(card,MagicLocationType.OwnersLibrary,MagicLocationType.Exile));
                                if (card.hasColor(color)) {
                                    game.doAction(new MagicPlayTokenAction(
                                        event.getPlayer(),
                                        TokenCardDefinitions.get("Faerie Rogue")
                                    ));
                                }
                            }
                        } as MagicEventAction,
                        "Chosen color\$."
                    ));
                }
            });
        }
    }
]
User avatar
melvin
AI Programmer
 
Posts: 1062
Joined: 21 Mar 2010, 12:26
Location: Singapore
Has thanked: 36 times
Been thanked: 459 times

Re: Adding new cards with Groovy

Postby melvin » 30 Jun 2013, 11:01

Staring work on the July release, 1.40. 1.39 includes Kodama of the Center Tree and Kodama of the North Tree, completing the cycle of legendary spirit creatures is the following card.

Image

Magarena/scripts/Kodama_of_the_South_Tree.txt
Code: Select all
name=Kodama of the South Tree
url=http://magiccards.info/chk/en/223.html
image=http://magiccards.info/scans/en/chk/223.jpg
value=4.111
rarity=R
type=Legendary,Creature
subtype=Spirit
cost={2}{G}{G}
pt=4/4
timing=main
requires_groovy_code
Magarena/scripts/Kodama_of_the_South_Tree.groovy
Code: Select all
[
    new MagicWhenYouCastSpiritOrArcaneTrigger() {
        @Override
        public MagicEvent executeTrigger(final MagicGame game,final MagicPermanent permanent,final MagicCardOnStack spell) {
            return new MagicEvent(
                permanent,
                this,
                "Each other creature PN controls gets +1/+1 and gains trample until end of turn."
            );
        }
        @Override
        public void executeEvent(final MagicGame game, final MagicEvent event) {
            final MagicTargetFilter<MagicPermanent> filter = new MagicOtherPermanentTargetFilter(
                MagicTargetFilter.TARGET_CREATURE,
                event.getPermanent()
            );
            final Collection<MagicPermanent> targets = game.filterPermanents(
                event.getPlayer(),
                filter
            );
            for (final MagicPermanent target : targets) {
                game.doAction(new MagicChangeTurnPTAction(target, 1, 1));
                game.doAction(new MagicSetAbilityAction(target, MagicAbility.Trample));
            }
        }
    }
]
User avatar
melvin
AI Programmer
 
Posts: 1062
Joined: 21 Mar 2010, 12:26
Location: Singapore
Has thanked: 36 times
Been thanked: 459 times

Re: Adding new cards with Groovy

Postby melvin » 07 Jul 2013, 01:49

Steam of Life, as requested by mecheng

Image

Magarena/scripts/Stream_of_Life.txt
Code: Select all
name=Stream of Life
url=http://magiccards.info/9e/en/272.html
image=http://magiccards.info/scans/en/9e/272.jpg
value=4.012
rarity=U
type=Sorcery
cost={X}{G}
timing=main
requires_groovy_code
Magarena/scripts/Stream_of_Life.groovy
Code: Select all
[
    new MagicSpellCardEvent() {
        @Override
        public MagicEvent getEvent(final MagicCardOnStack cardOnStack,final MagicPayedCost payedCost) {
            return new MagicEvent(
                cardOnStack,
                MagicTargetChoice.POS_TARGET_PLAYER,
                payedCost.getX(),
                this,
                "Target player\$ gains RN life."
            );
        }
        @Override
        public void executeEvent(final MagicGame game, final MagicEvent event) {
            event.processTargetPlayer(game, {
                final MagicPlayer player ->
                game.doAction(new MagicChangeLifeAction(player, event.getRefInt()));
            } as MagicPlayerAction);
        }
    }
]
User avatar
melvin
AI Programmer
 
Posts: 1062
Joined: 21 Mar 2010, 12:26
Location: Singapore
Has thanked: 36 times
Been thanked: 459 times

Re: Adding new cards with Groovy

Postby melvin » 07 Jul 2013, 02:03

Armored Ascension, as requested by mindx

Image

Magarena/scripts/Armored_Ascension.txt
Code: Select all
name=Armored Ascension
url=http://magiccards.info/m11/en/5.html
image=http://magiccards.info/scans/en/m11/5.jpg
value=2.366
rarity=U
type=Enchantment
subtype=Aura
cost={3}{W}
given_ability=flying
timing=aura
enchant=pump,pos creature
requires_groovy_code
Magarena/scripts/Armored_Ascension.groovy
Code: Select all
[
    new MagicStatic(MagicLayer.ModPT) {
        @Override
        public void modPowerToughness(final MagicPermanent source,final MagicPermanent permanent,final MagicPowerToughness pt) {
            final int amount = source.getController().getNrOfPermanentsWithSubType(MagicSubType.Plains);
            pt.add(amount,amount);
        }
        @Override
        public boolean accept(final MagicGame game,final MagicPermanent source,final MagicPermanent target) {
            return MagicStatic.acceptLinked(game, source, target);
        }
    }
]
User avatar
melvin
AI Programmer
 
Posts: 1062
Joined: 21 Mar 2010, 12:26
Location: Singapore
Has thanked: 36 times
Been thanked: 459 times

Re: Adding new cards with Groovy

Postby melvin » 12 Jul 2013, 13:30

Gaining of activated abilities has landed in current development version, which will become 1.40 (July release). This allows us to implement cards, such as the following:

Image

Magarena/scripts/Splinter_Twin.txt
Code: Select all
name=Splinter Twin
url=http://magiccards.info/roe/en/165.html
image=http://magiccards.info/scans/en/roe/165.jpg
value=3.867
rarity=R
type=Enchantment
subtype=Aura
cost={2}{R}{R}
timing=aura
enchant=copy,pos creature
requires_groovy_code
Magarena/scripts/Splinter_Twin.groovy
Code: Select all
def Copy = new MagicPermanentActivation(
        new MagicActivationHints(MagicTiming.Token),
        "Copy"
    ) {

    @Override
    public MagicEvent[] getCostEvent(final MagicPermanent source) {
        return [new MagicTapEvent(source)];
    }

    @Override
    public MagicEvent getPermanentEvent(final MagicPermanent source,final MagicPayedCost payedCost) {
        return new MagicEvent(
            source,
            this,
            "Put a token that's a copy of SN onto the battlefield. "+
            "That token has haste. Exile it at the beginning of the next end step."
        );
    }

    @Override
    public void executeEvent(final MagicGame game, final MagicEvent event) {
        final MagicPlayer player=event.getPlayer();
        final MagicCard card=MagicCard.createTokenCard(
            event.getPermanent().getCardDefinition(),
            player
        );
        game.doAction(new MagicPlayCardAction(
            card,
            player,
            [MagicPlayMod.HASTE, MagicPlayMod.EXILE_AT_END_OF_TURN]
        ));
    }
}

[
    new MagicStatic(MagicLayer.Ability) {
        @Override
        public void modAbilityFlags(final MagicPermanent source, final MagicPermanent permanent, final Set<MagicAbility> flags) {
            permanent.addActivation(Copy);
        }
        @Override
        public boolean accept(final MagicGame game,final MagicPermanent source,final MagicPermanent target) {
            return MagicStatic.acceptLinked(game, source, target);
        }
    }
]
User avatar
melvin
AI Programmer
 
Posts: 1062
Joined: 21 Mar 2010, 12:26
Location: Singapore
Has thanked: 36 times
Been thanked: 459 times

Re: Adding new cards with Groovy

Postby melvin » 14 Jul 2013, 14:06

The most complex card presented in this series so far

Image

Magarena/scripts/Olivia_Voldaren.txt
Code: Select all
name=Olivia Voldaren
url=http://magiccards.info/isd/en/215.html
image=http://magiccards.info/scans/en/isd/215.jpg
value=3.708
rarity=M
type=Legendary,Creature
subtype=Vampire
cost={2}{B}{R}
pt=3/3
ability=flying
timing=main
requires_groovy_code
Magarena/scripts/Olivia_Voldaren.groovy
Code: Select all
[
    new MagicPermanentActivation(
        new MagicActivationHints(MagicTiming.Removal),
        "Damage"
    ) {

        @Override
        public MagicEvent[] getCostEvent(final MagicPermanent source) {
            return [
                new MagicPayManaCostEvent(source, "{1}{R}")
            ];
        }

        @Override
        public MagicEvent getPermanentEvent(final MagicPermanent source, final MagicPayedCost payedCost) {
            final MagicTargetFilter<MagicPermanent> targetFilter = new MagicOtherPermanentTargetFilter(
                MagicTargetFilter.TARGET_CREATURE,
                source
            );
            final MagicTargetChoice targetChoice = new MagicTargetChoice(
                targetFilter,
                true,
                MagicTargetHint.Negative,
                "another target creature"
            );
            return new MagicEvent(
                source,
                targetChoice,
                new MagicDamageTargetPicker(1),
                this,
                "SN deals 1 damage to another target creature\$. " +
                "That creature becomes a Vampire in addition to its other types. " +
                "Put a +1/+1 counter on SN."
            );
        }

        @Override
        public void executeEvent(final MagicGame game, final MagicEvent event) {
            event.processTargetPermanent(game,new MagicPermanentAction() {
                public void doAction(final MagicPermanent creature) {
                    final MagicDamage damage = new MagicDamage(
                        event.getSource(),
                        creature,
                        1
                    );
                    game.doAction(new MagicDealDamageAction(damage));
                    game.doAction(new MagicAddStaticAction(creature, MagicStatic.Vampire));
                    game.doAction(new MagicChangeCountersAction(
                        event.getPermanent(),
                        MagicCounterType.PlusOne,
                        1,
                        true
                    ));
                }
            });
        }
    },
    new MagicPermanentActivation(
        new MagicActivationHints(MagicTiming.Removal),
        "Control"
    ) {

        @Override
        public MagicEvent[] getCostEvent(final MagicPermanent source) {
            return [
                new MagicPayManaCostEvent(source, "{3}{B}{B}")
            ];
        }

        @Override
        public MagicEvent getPermanentEvent(final MagicPermanent source, final MagicPayedCost payedCost) {
            return new MagicEvent(
                source,
                MagicTargetChoice.NEG_TARGET_VAMPIRE,
                MagicExileTargetPicker.create(),
                this,
                "Gain control of target Vampire\$ for as long as PN controls SN."
            );
        }

        @Override
        public void executeEvent(final MagicGame game, final MagicEvent event) {
            event.processTargetPermanent(game, {
                final MagicPermanent perm ->
                game.doAction(new MagicAddStaticAction(
                    event.getPermanent(),
                    MagicStatic.ControlAsLongAsYouControlSource(
                        event.getPlayer(),
                        perm
                    )
                ));
            } as MagicPermanentAction);
        }
    }
]
User avatar
melvin
AI Programmer
 
Posts: 1062
Joined: 21 Mar 2010, 12:26
Location: Singapore
Has thanked: 36 times
Been thanked: 459 times

Next

Return to Magarena

Who is online

Users browsing this forum: No registered users and 17 guests


Who is online

In total there are 17 users online :: 0 registered, 0 hidden and 17 guests (based on users active over the past 10 minutes)
Most users ever online was 4143 on 23 Jan 2024, 08:21

Users browsing this forum: No registered users and 17 guests

Login Form