It is currently 02 Sep 2025, 05:45
   
Text Size

Adding new cards with Groovy

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

Re: Adding new cards with Groovy

Postby hong yie » 01 Sep 2013, 14:18

want to try to script "aetherplasm", having trouble with the "comes into play blocking..." part. any idea? :)
User avatar
hong yie
Programmer
 
Posts: 216
Joined: 10 Mar 2013, 06:44
Location: Jakarta
Has thanked: 75 times
Been thanked: 9 times

Re: Adding new cards with Groovy

Postby melvin » 02 Sep 2013, 05:34

hong yie wrote:want to try to script "aetherplasm", having trouble with the "comes into play blocking..." part. any idea? :)
Not possible right now, the closest we have is MagicDeclareBlockerAction, i.e.
Code: Select all
// assuming attacker and blocker are defined earlier
game.doAction(new MagicDeclareBlockerAction(attacker, blocker));
However that would cause Ætherplasm to trigger again which it shouldn't. Will add in a new action that doesn't cause "whenever .. blocks" to trigger. For now, use the MagicDeclareBlockerAction first, we'll fix the script when merging the card.
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 » 04 Sep 2013, 02:14

Image

Magarena/scripts/Solemn_Simulacrum.txt
Code: Select all
name=Solemn Simulacrum
url=http://magiccards.info/m12/en/217.html
image=http://magiccards.info/scans/en/m12/217.jpg
value=3.524
rarity=R
type=Artifact,Creature
subtype=Golem
cost={4}
pt=2/2
ability=die may draw card
timing=main
requires_groovy_code=Farhaven Elf
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 » 04 Sep 2013, 03:09

Image

Magarena/scripts/Ingot_Chewer.txt
Code: Select all
name=Ingot Chewer
url=http://magiccards.info/lw/en/180.html
image=http://magiccards.info/scans/en/lw/180.jpg
value=3.524
rarity=C
type=Creature
subtype=Elemental
cost={4}{R}
pt=3/3
ability=enters destroy target artifact.;evoke {R}
timing=main
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 » 05 Sep 2013, 09:30

Combination of two new features in 1.41 allows this card to be completely described in card script, without groovy script.

1) New "lord" ability
2) All abilities can be granted (previously only keyword abilities can be granted)

Image

Magarena/scripts/Chromatic_Lantern.txt
Code: Select all
name=Chromatic Lantern
url=http://magiccards.info/rtr/en/226.html
image=http://magiccards.info/scans/en/rtr/226.jpg
value=2.428
rarity=R
type=Artifact
cost={3}
ability=lord lands you control have tap add mana any;\
        tap add mana any
timing=main
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 » 05 Sep 2013, 11:55

This groovy stuff is totally groovy. Fantastic progress melvin and associates!

Magarena is just kicking my butt lately. With all the card and deck variety now I never know what the AI is going to throw at me next.
User avatar
Huggybaby
Administrator
 
Posts: 3227
Joined: 15 Jan 2006, 19:44
Location: Finally out of Atlanta
Has thanked: 749 times
Been thanked: 601 times

Re: Adding new cards with Groovy

Postby melvin » 06 Sep 2013, 08:54

@Huggybaby: Thanks for the encouragement! Converting all the existing cards to Groovy was a mammoth task, I'm glad we pushed through on that so that card scripters can see how every card is implemented.

Image

Magarena/scripts/Flusterstorm.txt
Code: Select all
name=Flusterstorm
url=http://magiccards.info/cmd/en/46.html
image=http://magiccards.info/scans/en/cmd/46.jpg
value=4.644
rarity=R
type=Instant
cost={U}
ability=storm
timing=counter
requires_groovy_code
Magarena/scripts/Flusterstorm.groovy
Code: Select all
[
    new MagicSpellCardEvent() {
        @Override
        public MagicEvent getEvent(final MagicCardOnStack cardOnStack,final MagicPayedCost payedCost) {
            return new MagicEvent(
                cardOnStack,
                MagicTargetChoice.NEG_TARGET_INSTANT_OR_SORCERY_SPELL,
                this,
                "Counter target instant or sorcery spell\$ unless its controller pays {1}."
            );
        }
        @Override
        public void executeEvent(final MagicGame game, final MagicEvent event) {
            event.processTargetCardOnStack(game,new MagicCardOnStackAction() {
                public void doAction(final MagicCardOnStack targetSpell) {
                    game.addEvent(new MagicCounterUnlessEvent(event.getSource(),targetSpell,MagicManaCost.create("{1}")));
                }
            });
        }
    }
]
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 » 06 Sep 2013, 13:27

Image

Magarena/scripts/Relic_of_Progenitus.txt
Code: Select all
name=Relic of Progenitus
url=http://magiccards.info/mma/en/213.html
image=http://magiccards.info/scans/en/mma/213.jpg
value=2.428
rarity=C
type=Artifact
cost={1}
timing=main
requires_groovy_code
Magarena/scripts/Relic_of_Progenitus.groovy
Code: Select all
def action = {
    final MagicGame game, final MagicEvent event ->
    event.processTargetCard(game,new MagicCardAction() {
        public void doAction(final MagicCard card) {
            game.doAction(new MagicRemoveCardAction(card,MagicLocationType.Graveyard));
            game.doAction(new MagicMoveCardAction(card,MagicLocationType.Graveyard,MagicLocationType.Exile));
        }
    });
} as MagicEventAction

[
    new MagicPermanentActivation(
        new MagicActivationHints(MagicTiming.Main),
        "Exile one"
    ) {
        @Override
        public Iterable<MagicEvent> getCostEvent(final MagicPermanent source) {
            return [new MagicTapEvent(source)];
        }
        @Override
        public MagicEvent getPermanentEvent(final MagicPermanent source,final MagicPayedCost payedCost) {
            return new MagicEvent(
                source,
                MagicTargetChoice.TARGET_PLAYER,
                this,
                "Target player\$ exiles a card from his or her graveyard."
            );
        }
        @Override
        public void executeEvent(final MagicGame game, final MagicEvent event) {
            event.processTargetPlayer(game, {
                final MagicPlayer targetPlayer ->
                game.addEvent(new MagicEvent(
                    event.getSource(),
                    targetPlayer,
                    new MagicTargetChoice("a card from your graveyard"),
                    MagicGraveyardTargetPicker.ExileOwn,
                    action,
                    "PN exiles a card\$ from his or her graveyard."
                ));
            } as MagicPlayerAction);
        }
    },
    new MagicPermanentActivation(
        new MagicActivationHints(MagicTiming.Main),
        "Exile all"
    ) {
        @Override
        public Iterable<MagicEvent> getCostEvent(final MagicPermanent source) {
            return [
                new MagicPayManaCostEvent(source, "{1}"),
                new MagicExileEvent(source)
            ];
        }
        @Override
        public MagicEvent getPermanentEvent(final MagicPermanent source,final MagicPayedCost payedCost) {
            return new MagicEvent(
                source,
                this,
                "Exile all cards from all graveyards. Draw a card."
            );
        }
        @Override
        public void executeEvent(final MagicGame game, final MagicEvent event) {
            for (final MagicPlayer player : game.getPlayers()) {
                for (final MagicCard card : new MagicCardList(player.getGraveyard())) {
                    game.doAction(new MagicRemoveCardAction(card, MagicLocationType.Graveyard));
                    game.doAction(new MagicMoveCardAction(card, MagicLocationType.Graveyard, MagicLocationType.Exile));
                }
            }
            game.doAction(new MagicDrawAction(event.getPlayer()));
        }
    }
]
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 » 06 Sep 2013, 13:52

Image

Magarena/scripts/Shard_Volley.txt
Code: Select all
name=Shard Volley
url=http://magiccards.info/mt/en/103.html
image=http://magiccards.info/scans/en/mt/103.jpg
value=4.644
removal=3
rarity=C
type=Instant
cost={R}
timing=removal
requires_groovy_code
Magarena/scripts/Shard_Volley.groovy
Code: Select all
[
    new MagicAdditionalCost() {
        @Override
        public MagicEvent getEvent(final MagicSource source) {
            return new MagicSacrificePermanentEvent(source, MagicTargetChoice.SACRIFICE_LAND);
        }
    },
    new MagicSpellCardEvent() {
        @Override
        public MagicEvent getEvent(final MagicCardOnStack cardOnStack,final MagicPayedCost payedCost) {
            return new MagicEvent(
                cardOnStack,
                MagicTargetChoice.NEG_TARGET_CREATURE_OR_PLAYER,
                new MagicDamageTargetPicker(3),
                this,
                "SN deals 3 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,3);
                    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 mike » 06 Sep 2013, 19:26

As a little helper for finding a similar card as a starting point I added search functionality the Project Firemind that lets you search in the cards abilities (original text) and shows you the Magarena scripts for it. Hope this is useful to someone.

http://www.firemind.ch/cards/search
User avatar
mike
Programmer
 
Posts: 128
Joined: 05 Jul 2013, 17:00
Has thanked: 0 time
Been thanked: 29 times

Re: Adding new cards with Groovy

Postby hong yie » 07 Sep 2013, 05:42

- do we have someway to apply "tap an untapped ... creature" to pay a cost of ability before? i see many interesting cards use this "tap" to pay a cost of its ability.
- is there a way to change the property of a card while its on the battlefield? beside changing power toughness, including name, casting cost, color, type, or add new ability into it / remove all abilities from it?
- how to script "discard a creature card:..." as a cost of an ability? filter?
- need MagicTargetChoice.SACRIFICE_NON_VAMPIRE() please...
No such property: SACRIFICE_NON_VAMPIRE for class: java.lang.Class <magic.model.choice.MagicTargetChoice>

thanks :)
User avatar
hong yie
Programmer
 
Posts: 216
Joined: 10 Mar 2013, 06:44
Location: Jakarta
Has thanked: 75 times
Been thanked: 9 times

Re: Adding new cards with Groovy

Postby melvin » 08 Sep 2013, 13:55

mike wrote:As a little helper for finding a similar card as a starting point I added search functionality the Project Firemind that lets you search in the cards abilities (original text) and shows you the Magarena scripts for it. Hope this is useful to someone.
http://www.firemind.ch/cards/search
I do something very similar when implementing cards. I open up a text file containing the rules text for existing cards and use it to search for similar cards. Thanks for the nice work :)
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 Sep 2013, 14:12

hong yie wrote:do we have someway to apply "tap an untapped ... creature" to pay a cost of ability before? i see many interesting cards use this "tap" to pay a cost of its ability.
Not possible at the moment but doable. Any specific card you are looking at?

hong yie wrote:is there a way to change the property of a card while its on the battlefield? beside changing power toughness, including name, casting cost, color, type, or add new ability into it / remove all abilities from it?
chagne Name - no
change Casting cost - no
change Color - yes, https://code.google.com/p/magarena/sour ... age.groovy
change Type - yes, same as above
add Ability - yes, use permanent.addAbility or flags.add (sorry for the confusion, will improve this in the future)
remove ability - yes but only those in flags for now using flags.remove

hong yie wrote:how to script "discard a creature card:..." as a cost of an ability? filter?
Not possible at the moment but doable. Any specific card you are looking at?

hong yie wrote:need MagicTargetChoice.SACRIFICE_NON_VAMPIRE() please...
No such property: SACRIFICE_NON_VAMPIRE for class: java.lang.Class <magic.model.choice.MagicTargetChoice>
Added for next release
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 Sep 2013, 14:14

Image

Magarena/scripts/Xathrid_Necromancer.txt
Code: Select all
name=Xathrid Necromancer
url=http://magiccards.info/m14/en/123.html
image=http://magiccards.info/scans/en/m14/123.jpg
value=3.721
rarity=R
type=Creature
subtype=Human,Wizard
cost={2}{B}
pt=2/2
timing=main
requires_groovy_code
Magarena/scripts/Xathrid_Necromancer.groovy
Code: Select all
[
    new MagicWhenOtherDiesTrigger() {
        @Override
        public MagicEvent executeTrigger(final MagicGame game, final MagicPermanent permanent, final MagicPermanent diedPermanent) {
            return (permanent == diedPermanent ||
                    (diedPermanent.hasSubType(MagicSubType.Human) &&
                     diedPermanent.isCreature() &&
                     permanent.isFriend(diedPermanent))) ?
                new MagicEvent(
                    permanent,
                    this,
                    "PN puts a 2/2 black Zombie creature token onto the battlefield tapped."
                ):
                MagicEvent.NONE;
        }
        @Override
        public void executeEvent(final MagicGame game, final MagicEvent event) {
            game.doAction(new MagicPlayCardAction(
                MagicCard.createTokenCard(
                    TokenCardDefinitions.get("Zombie"),
                    event.getPlayer()
                ),
                [MagicPlayMod.TAPPED]
            ));
        }
    }
]
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 Sep 2013, 14:20

Image

Magarena/scripts/Foundry_Street_Denizen.txt
Code: Select all
name=Foundry Street Denizen
url=http://magiccards.info/gtc/en/92.html
image=http://magiccards.info/scans/en/gtc/92.jpg
value=3.721
rarity=C
type=Creature
subtype=Goblin,Warrior
cost={R}
pt=1/1
timing=main
requires_groovy_code
Magarena/scripts/Foundry_Street_Denizen.groovy
Code: Select all
[
    new MagicWhenOtherComesIntoPlayTrigger() {
        @Override
        public boolean accept(final MagicPermanent source, final MagicPermanent other) {
            return other != source &&
                   other.hasColor(MagicColor.Red) &&
                   other.isCreature() &&
                   other.isFriend(source);
        }
        @Override
        public MagicEvent executeTrigger(final MagicGame game, final MagicPermanent source, final MagicPermanent other) {
            return new MagicEvent(
                source,
                this,
                "SN gets +1/+0 until end of turn."
            );
        }
        @Override
        public void executeEvent(final MagicGame game, final MagicEvent event) {
            game.doAction(new MagicChangeTurnPTAction(event.getPermanent(),1,0));
        }
    }
]
User avatar
melvin
AI Programmer
 
Posts: 1062
Joined: 21 Mar 2010, 12:26
Location: Singapore
Has thanked: 36 times
Been thanked: 459 times

PreviousNext

Return to Magarena

Who is online

Users browsing this forum: No registered users and 5 guests

Main Menu

User Menu

Our Partners


Who is online

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

Login Form