Adding new cards with Groovy
by ubeefx
Moderators: ubeefx, beholder, melvin, ShawnieBoy, Lodici, CCGHQ Admins
Re: Adding new cards with Groovy
by ShawnieBoy » 01 Mar 2014, 18:38
I've submitted a test scenario - though I was only half-joking
TestReaperKing

-
ShawnieBoy - Programmer
- Posts: 601
- Joined: 02 Apr 2012, 22:42
- Location: UK
- Has thanked: 80 times
- Been thanked: 50 times
Re: Adding new cards with Groovy
by Lodici » 02 Mar 2014, 06:48
Thanks. Interesting, it even wipes out the player info!ShawnieBoy wrote:I've submitted a test scenario - though I was only half-jokingTestReaperKing

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
by ShawnieBoy » 02 Mar 2014, 07:47
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.
-
ShawnieBoy - Programmer
- Posts: 601
- Joined: 02 Apr 2012, 22:42
- Location: UK
- Has thanked: 80 times
- Been thanked: 50 times
Re: Adding new cards with Groovy
by melvin » 02 Mar 2014, 09:46
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.

Magarena/scripts/Snapcaster_Mage.txt

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
- 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."
));
});
}
}
}
]
-
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
by hong yie » 02 Mar 2014, 13:10
is this mean all flashback cards is supported now? 

-
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
by melvin » 02 Mar 2014, 13:36
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.
-
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
by Lodici » 02 Mar 2014, 17:33
How about something like...?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.
Re: Adding new cards with Groovy
by ShawnieBoy » 02 Mar 2014, 19:07
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)
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.)

This would be how it would look. (ie. not different at all)
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.)
-
ShawnieBoy - Programmer
- Posts: 601
- Joined: 02 Apr 2012, 22:42
- Location: UK
- Has thanked: 80 times
- Been thanked: 50 times
Re: Adding new cards with Groovy
by Lodici » 02 Mar 2014, 20:32
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).
This might also require the fix for issue 494 (https://bitbucket.org/lodici/magarena/c ... e73ff6a201).
Re: Adding new cards with Groovy
by melvin » 09 Mar 2014, 10:46

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
- 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);
}
}
]
-
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
by ShawnieBoy » 09 Mar 2014, 12:43
Nice one! 
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)

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)
-
ShawnieBoy - Programmer
- Posts: 601
- Joined: 02 Apr 2012, 22:42
- Location: UK
- Has thanked: 80 times
- Been thanked: 50 times
Re: Adding new cards with Groovy
by melvin » 09 Mar 2014, 13:10
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.
-
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
by melvin » 10 Mar 2014, 12:45

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
- 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
));
}
});
}
}
]
-
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
by melvin » 18 Mar 2014, 14:13

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
- 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);
}
}
]
-
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
by ShawnieBoy » 18 Mar 2014, 17:57
Nice!
Another thought, looking at Birthing Pod again - Transmute should be implementable using similar mechanics.
Another thought, looking at Birthing Pod again - Transmute should be implementable using similar mechanics.
-
ShawnieBoy - Programmer
- Posts: 601
- Joined: 02 Apr 2012, 22:42
- Location: UK
- Has thanked: 80 times
- Been thanked: 50 times
Who is online
Users browsing this forum: No registered users and 2 guests