Page 20 of 28

Re: Adding new cards with Groovy

PostPosted: 01 Mar 2014, 18:38
by ShawnieBoy
I've submitted a test scenario - though I was only half-joking :) TestReaperKing

Re: Adding new cards with Groovy

PostPosted: 02 Mar 2014, 06:48
by Lodici
ShawnieBoy wrote:I've submitted a test scenario - though I was only half-joking :) TestReaperKing
Thanks. Interesting, it even wipes out the player info! :D
Untitled.png

Is there any reason why, in extreme cases like this, you could not just prompt the player to pay 10 and leave it for them to decide instead of offering all possible options? As they tap the prompt would count down until the required mana count has been reached. Alternatively, I am sure we could probably add a JScrollPane or even use something like a JList instead of multiple JButtons.

Re: Adding new cards with Groovy

PostPosted: 02 Mar 2014, 07:47
by ShawnieBoy
The total mana cost for Reaper King can vary from 5 -> 10. It's the same problem we had with Phyrexian Mana, unable to give an extra prompt to pay mana or life for each step, but this time 2 colorless mana or 1 colored.

Re: Adding new cards with Groovy

PostPosted: 02 Mar 2014, 09:46
by melvin
Another card inspired by the recent Pro Tour BNG, where I noticed players cast the card from graveyard immediately after playing Snapcaster Mage. This reminded me that the Varolz trick can be used to implement Snapcaster Mage.

Image

Magarena/scripts/Snapcaster_Mage.txt
Code: Select all
name=Snapcaster Mage
url=http://magiccards.info/isd/en/78.html
image=http://mtgimage.com/card/snapcaster%20mage.jpg
value=3.723
rarity=R
type=Creature
subtype=Human,Wizard
cost={1}{U}
pt=2/1
ability=flash
timing=main
requires_groovy_code
Magarena/scripts/Snapcaster_Mage.groovy
Code: Select all
def A_PAYABLE_INSTANT_OR_SORCERY_CARD_FROM_YOUR_GRAVEYARD = new MagicTargetChoice(
    MagicTargetFilter.PAYABLE_INSTANT_OR_SORCERY_FROM_GRAVEYARD,
    "a instant or sorcery card from your graveyard"
);

[
    new MagicWhenComesIntoPlayTrigger() {
        @Override
        public MagicEvent executeTrigger(final MagicGame game, final MagicPermanent permanent, final MagicPayedCost payedCost) {
            return new MagicEvent(
                permanent,
                new MagicMayChoice(
                    A_PAYABLE_INSTANT_OR_SORCERY_CARD_FROM_YOUR_GRAVEYARD
                ),
                MagicGraveyardTargetPicker.PutOntoBattlefield,
                this,
                "PN may\$ cast target instant or sorcery card\$ from his or her graveyard, then exile it."
            );
        }
        @Override
        public void executeEvent(final MagicGame game, final MagicEvent event) {
            if (event.isYes()) {
                event.processTargetCard(game, {
                    final MagicCard card ->
                    game.addEvent(new MagicPayManaCostEvent(card,card.getCost()));
                    game.addEvent(new MagicEvent(
                        card,
                        {
                            final MagicGame G, final MagicEvent E ->
                            G.doAction(new MagicRemoveCardAction(E.getCard(),MagicLocationType.Graveyard));
                            final MagicCardOnStack cardOnStack=new MagicCardOnStack(card,event.getPlayer(),game.getPayedCost());
                            cardOnStack.setMoveLocation(MagicLocationType.Exile);
                            game.doAction(new MagicPutItemOnStackAction(cardOnStack));
                        },
                        "Cast SN."
                    ));
                });
            }
        }
    }
]

Re: Adding new cards with Groovy

PostPosted: 02 Mar 2014, 13:10
by hong yie
is this mean all flashback cards is supported now? :)

Re: Adding new cards with Groovy

PostPosted: 02 Mar 2014, 13:36
by melvin
No, technically the card didn't gain flashback. Snapcaster Mage is implemented as if it has the ability: When Snapcaster Mage enters the battlefield, you may cast target instant or sorcery card from your graveyard by paying its mana cost, then exile it.

Re: Adding new cards with Groovy

PostPosted: 02 Mar 2014, 17:33
by Lodici
ShawnieBoy wrote:The total mana cost for Reaper King can vary from 5 -> 10. It's the same problem we had with Phyrexian Mana, unable to give an extra prompt to pay mana or life for each step, but this time 2 colorless mana or 1 colored.
How about something like...?
Untitled.png

Re: Adding new cards with Groovy

PostPosted: 02 Mar 2014, 19:07
by ShawnieBoy
Cool :) - It was more the coding side of things I think though - The normal prompt for mana would work for {2/W} etc if it could accept and highlight all colorless mana sources and relevant color sources. If the colored source was selected, it would then move to the next mana as normal (for Reaper King, {2/U}), otherwise wait for another colorless source to be chosen. The multi-button approach was only used as it's being used for Phyrexian mana.

This would be how it would look. (ie. not different at all)
Payment Hybrid .png
Colorless Hybrid Payment Prompt

Phyrexian mana can't use the normal mana prompt, as there's nowhere to select 'Pay 2 life', so that's why the button prompt is being used. So something like this would be perfect if the code behind it could work. (Assuming that in this example, black mana sources are being highlighted on the battlefield. So a choice between the button or mana, if mana is possible, if not then no prompt and 2 life is paid right away.)
payment phyrexian.png
Phyrexian Payment Prompt

Re: Adding new cards with Groovy

PostPosted: 02 Mar 2014, 20:32
by Lodici
I have updated the game prompt so that it will show a scrollbar if required which means you can at least access all the options for Reaper King although it is not very aesthetic (http://bitbucket.org/lodici/magarena/co ... 507510bee8).
This might also require the fix for issue 494 (https://bitbucket.org/lodici/magarena/c ... e73ff6a201).

Re: Adding new cards with Groovy

PostPosted: 09 Mar 2014, 10:46
by melvin
Image

Magarena/scripts/Birthing_Pod.txt
Code: Select all
name=Birthing Pod
url=http://magiccards.info/query?q=%21birthing%20pod
image=http://mtgimage.com/card/birthing%20pod.jpg
value=4.588
rarity=R
type=Artifact
cost={3}{P/G}
ability=alt cost {3}, Pay 2 life named Pay 2 life
timing=artifact
requires_groovy_code
Magarena/scripts/Birthing_Pod.groovy
Code: Select all
def action = {
    final MagicGame game, final MagicEvent event ->
    final int cmc = event.getRefInt();
    final MagicTargetFilter filter = new MagicTargetFilter.MagicCMCCardFilter(
        MagicTargetFilter.Factory.card(MagicTargetType.Library, MagicType.Creature),
        MagicTargetFilter.Operator.EQUAL,
        cmc
    );
    final MagicTargetChoice choice = new MagicTargetChoice(
        filter,
        "a creature card with converted mana cost ${cmc} from your library"
    );
    game.addEvent(new MagicSearchOntoBattlefieldEvent(
        event,
        choice
    ));
}

def event = {
    final MagicPermanent source, final MagicPayedCost payedCost ->
    // canPlay check uses NO_COST
    if (payedCost == MagicPayedCost.NO_COST) {
        return MagicEvent.NONE;
    }
    final int cmc = ((MagicPermanent)payedCost.getTarget()).getConvertedCost() + 1;
    return new MagicEvent(
        source,
        cmc,
        action,
        "PN searches PN's library for a creature card with converted mana cost RN, put that card onto the battlefield, then shuffle your library."
    );
}

[
    new MagicPermanentActivation(
        [MagicCondition.SORCERY_CONDITION],
        new MagicActivationHints(MagicTiming.Main),
        "Search"
    ) {

        @Override
        public Iterable<MagicEvent> getCostEvent(final MagicPermanent source) {
            return [
                new MagicPayManaCostEvent(source, "{1}{P/G}"),
                new MagicTapEvent(source),
                new MagicSacrificePermanentEvent(source, MagicTargetChoice.SACRIFICE_CREATURE),
            ];
        }

        @Override
        public MagicEvent getPermanentEvent(final MagicPermanent source, final MagicPayedCost payedCost) {
            return event(source, payedCost);
        }
    },
    new MagicPermanentActivation(
        [MagicCondition.SORCERY_CONDITION],
        new MagicActivationHints(MagicTiming.Main),
        "Pay 2 life"
    ) {

        @Override
        public Iterable<MagicEvent> getCostEvent(final MagicPermanent source) {
            return [
                new MagicPayManaCostEvent(source, "{1}"),
                new MagicPayLifeEvent(source, 2),
                new MagicTapEvent(source),
                new MagicSacrificePermanentEvent(source, MagicTargetChoice.SACRIFICE_CREATURE),
            ];
        }
   
        @Override
        public MagicEvent getPermanentEvent(final MagicPermanent source, final MagicPayedCost payedCost) {
            return event(source, payedCost);
        }
    }
]

Re: Adding new cards with Groovy

PostPosted: 09 Mar 2014, 12:43
by ShawnieBoy
Nice one! :D

Just another idea - most non-mana costs in CostEvent are essentially effects. Could linking them to RuleEventAction help prevent having to duplicate entries (eg. The BounceBasicLand, BounceCreature, BounceLand, BounceSelf entries)

Re: Adding new cards with Groovy

PostPosted: 09 Mar 2014, 13:10
by melvin
Yes, that would work. At first, it seems that costs are simpler than effects, so I made them separate. As we add more, it gets a bit reptitive, the duplication that can be eliminated if MagicCostEvent is merged into MagicRuleEventAction.

Re: Adding new cards with Groovy

PostPosted: 10 Mar 2014, 12:45
by melvin
Image

Magarena/scripts/Detention_Sphere.txt
Code: Select all
name=Detention Sphere
url=http://magiccards.info/query?q=%21detention%20sphere
image=http://mtgimage.com/card/detention%20sphere.jpg
value=4.000
rarity=R
type=Enchantment
cost={1}{W}{U}
ability=leaves return exile
timing=enchantment
requires_groovy_code
Magarena/scripts/Detention_Sphere.groovy
Code: Select all
def filter = new MagicPermanentFilterImpl() {
    public boolean accept(final MagicGame game,final MagicPlayer player,final MagicPermanent target) {
        return target.isLand() == false && target.getName().equals("Detention Sphere") == false;
    }
};

def choice = new MagicTargetChoice(filter, "target nonland permanent not named Detention Sphere");

[
    new MagicWhenComesIntoPlayTrigger() {
        @Override
        public MagicEvent executeTrigger(final MagicGame game,final MagicPermanent permanent, final MagicPayedCost payedCost) {
            return new MagicEvent(
                permanent,
                choice,
                MagicExileTargetPicker.create(),
                this,
                "Exile target nonland permanent\$ not named Detention Sphere and all other permanents with the same name as that permanent."
            );
        }
        @Override
        public void executeEvent(final MagicGame game, final MagicEvent event) {
            event.processTargetPermanent(game, {
                final MagicPermanent permanent ->
                final Collection<MagicPermanent> targets = game.filterPermanents(
                    event.getPlayer(),
                    new MagicTargetFilter.NameTargetFilter(permanent.getName())
                );
                for (final MagicPermanent target : targets) {
                    game.doAction(new MagicExileUntilThisLeavesPlayAction(
                        event.getPermanent(),
                        target
                    ));
                }
            });
        }
    }
]

Re: Adding new cards with Groovy

PostPosted: 18 Mar 2014, 14:13
by melvin
Image

Magarena/scripts/Spellskite.txt
Code: Select all
name=Spellskite
url=http://magiccards.info/query?q=%21spellskite
image=http://mtgimage.com/card/spellskite.jpg
value=3.723
rarity=R
type=Artifact,Creature
subtype=Horror
cost={2}
pt=0/4
timing=main
requires_groovy_code
Magarena/scripts/Spellskite.groovy
Code: Select all
def action = {
    final MagicGame game, final MagicEvent event ->
    event.processTargetItemOnStack(game, {
        final MagicItemOnStack item ->
        game.doAction(new MagicChangeTargetAction(item, event.getPermanent()));
    });
}

def event = {
    final MagicPermanent source ->
    return new MagicEvent(
        source,
        new MagicTargetChoice(MagicTargetFilter.SPELL_OR_ABILITY_WITH_TARGET, MagicTargetHint.Negative, "target spell or ability"),
        action,
        "Change the target of target spell or ability\$ to SN."
    );
}

[
    new MagicPermanentActivation(
        new MagicActivationHints(MagicTiming.Spell),
        "Retarget"
    ) {

        @Override
        public Iterable<MagicEvent> getCostEvent(final MagicPermanent source) {
            return [new MagicPayManaCostEvent(source, "{U}")];
        }

        @Override
        public MagicEvent getPermanentEvent(final MagicPermanent source,final MagicPayedCost payedCost) {
            return event(source);
        }
    },
    new MagicPermanentActivation(
        new MagicActivationHints(MagicTiming.Spell),
        "Pay 2 life"
    ) {

        @Override
        public Iterable<MagicEvent> getCostEvent(final MagicPermanent source) {
            return [new MagicPayLifeEvent(source, 2)];
        }

        @Override
        public MagicEvent getPermanentEvent(final MagicPermanent source,final MagicPayedCost payedCost) {
            return event(source);
        }
    }
]

Re: Adding new cards with Groovy

PostPosted: 18 Mar 2014, 17:57
by ShawnieBoy
Nice!

Another thought, looking at Birthing Pod again - Transmute should be implementable using similar mechanics.