Page 8 of 28

Re: Adding new cards with Groovy

PostPosted: 01 Sep 2013, 14:18
by hong yie
want to try to script "aetherplasm", having trouble with the "comes into play blocking..." part. any idea? :)

Re: Adding new cards with Groovy

PostPosted: 02 Sep 2013, 05:34
by melvin
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.

Re: Adding new cards with Groovy

PostPosted: 04 Sep 2013, 02:14
by melvin
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

Re: Adding new cards with Groovy

PostPosted: 04 Sep 2013, 03:09
by melvin
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

Re: Adding new cards with Groovy

PostPosted: 05 Sep 2013, 09:30
by melvin
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

Re: Adding new cards with Groovy

PostPosted: 05 Sep 2013, 11:55
by Huggybaby
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.

Re: Adding new cards with Groovy

PostPosted: 06 Sep 2013, 08:54
by melvin
@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}")));
                }
            });
        }
    }
]

Re: Adding new cards with Groovy

PostPosted: 06 Sep 2013, 13:27
by melvin
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()));
        }
    }
]

Re: Adding new cards with Groovy

PostPosted: 06 Sep 2013, 13:52
by melvin
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));
                }
            });
        }
    }
]

Re: Adding new cards with Groovy

PostPosted: 06 Sep 2013, 19:26
by mike
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

Re: Adding new cards with Groovy

PostPosted: 07 Sep 2013, 05:42
by hong yie
- 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 :)

Re: Adding new cards with Groovy

PostPosted: 08 Sep 2013, 13:55
by melvin
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 :)

Re: Adding new cards with Groovy

PostPosted: 08 Sep 2013, 14:12
by melvin
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

Re: Adding new cards with Groovy

PostPosted: 08 Sep 2013, 14:14
by melvin
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]
            ));
        }
    }
]

Re: Adding new cards with Groovy

PostPosted: 08 Sep 2013, 14:20
by melvin
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));
        }
    }
]