Adding new cards with Groovy
by ubeefx
Moderators: ubeefx, beholder, melvin, ShawnieBoy, Lodici, CCGHQ Admins
Re: Adding new cards with Groovy
by melvin » 08 Feb 2014, 08:00
Your right, I'd forgotten that the auto payment only occurs during MagicStackGetChoicesEvent.java, which occurs for events that go on the stack. In this case, as the event doesn't go on the stack, the payment has to be made manually by evoking event.payManaCost(game) in the isYes() case. See MagicCounterUnlessEvent.java for an example.ShawnieBoy wrote:Hmm, I've tried that, but the computer has a habit of selecting 'Yes' but then not paying the mana.
-
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 » 08 Feb 2014, 14:14
Thanks so much, been trying to get this to work for ages - Did look in the MagicCounterUnlessEvent, but didn't quite see what event.payManaCost(game) was doing. One thing I have noticed though, is that the mana enforcement has kinda gone the other way.
The computer was trying to bounce one of its own creatures (A good thing), but ended up paying the mana instead
The computer was trying to bounce one of its own creatures (A good thing), but ended up paying the mana instead

-
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 jerichopumpkin » 10 Feb 2014, 22:04
I've been trying to add Deus of Calamity, but something is not right. The strange thing is that magarena does not crash, but the game does not start if the card is in one of the decks...
Deus_of_Calamity.txt
Deus_of_Calamity.txt
- Code: Select all
name=Deus of Calamity
url=http://magiccards.info/shm/en/204.html
image=http://magiccards.info/scans/en/shm/204.jpg
value=4.214
rarity=R
type=Creature
subtype=Avatar,Spirit
cost={R/G}{R/G}{R/G}{R/G}{R/G}
pt=6/6
ability=trample
timing=main
requires_groovy_code
- Code: Select all
def LAND_YOUR_OPPONENT_CONTROLS = new MagicPermanentFilterImpl() {
public boolean accept(final MagicGame game,final MagicPlayer player,final MagicPermanent target) {
return target.isLand() && target.isOpponent(player);
}
};
def TARGET_LAND_YOUR_OPPONENT_CONTROLS = new MagicTargetChoice(
LAND_YOUR_OPPONENT_CONTROLS,
"a land opponent controls"
);
[
new MagicWhenDamageIsDealtTrigger() {
@Override
public MagicEvent executeTrigger(final MagicGame game,final MagicPermanent permanent,final MagicDamage damage) {
return (damage.getSource() == permanent &&
permanent.isOpponent(damage.getTarget()) &&
damage.getAmount() >= 6) ?
return new MagicEvent(
source,
TARGET_LAND_YOUR_OPPONENT_CONTROLS,
MagicDestroyTargetPicker.Destroy,
this,
"Destroy target land\$."
):
MagicEvent.NONE;
}
@Override
public void executeEvent(final MagicGame game, final MagicEvent event) {
game.doAction(new MagicDestroyAction(event.getPermanent()));
}
}
]
- jerichopumpkin
- Posts: 212
- Joined: 12 Sep 2013, 11:21
- Has thanked: 19 times
- Been thanked: 13 times
Re: Adding new cards with Groovy
by melvin » 11 Feb 2014, 02:05
1)jerichopumpkin wrote:I've been trying to add Deus of Calamity, but something is not right.
- Code: Select all
return (damage.getSource() == permanent &&
permanent.isOpponent(damage.getTarget()) &&
damage.getAmount() >= 6) ?
return new MagicEvent(
2)
- Code: Select all
new MagicEvent(
source,
TARGET_LAND_YOUR_OPPONENT_CONTROLS,
MagicDestroyTargetPicker.Destroy,
this,
"Destroy target land\$."
):
-
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 jerichopumpkin » 11 Feb 2014, 07:39

- jerichopumpkin
- Posts: 212
- Joined: 12 Sep 2013, 11:21
- Has thanked: 19 times
- Been thanked: 13 times
Re: Adding new cards with Groovy
by melvin » 11 Feb 2014, 12:31
I'd like to get addition info on the above which seems odd. Magarena should crash when it tried to load the card in a deck. If it doesn't not crash, what happens when the card is in one of the decks? Does some kind of dialog pop up? Would be great if you could attach a screenshot of the state the game is in when it gets stuck.jerichopumpkin wrote:The strange thing is that magarena does not crash, but the game does not start if the card is in one of the decks
-
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 jerichopumpkin » 11 Feb 2014, 17:02
It seems to enter an infinite loop. Magarena is just stuck here:
Then if you press Esc, you can access the running duel menu. Everything works, except for "Restart Duel" and "Concede Game". Clicking either of them leads to a crash:
And the screen capture:
- starting a game with Deus of Calamity with wrong groovy
Then if you press Esc, you can access the running duel menu. Everything works, except for "Restart Duel" and "Concede Game". Clicking either of them leads to a crash:
crash.log
- (2.81 KiB) Downloaded 338 times
And the screen capture:
- jerichopumpkin
- Posts: 212
- Joined: 12 Sep 2013, 11:21
- Has thanked: 19 times
- Been thanked: 13 times
Re: Adding new cards with Groovy
by ShawnieBoy » 11 Feb 2014, 19:24
This has already been fixed for 1.47 - try using that one 

-
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 ShawnieBoy » 13 Feb 2014, 18:06
While trundling through groovy codes, I've been beginning to wonder:
I'm always willing to get more stuff scriptable if it can stand up against a groovy version
Or incorporating the script card definitions into groovy, so only one file is needed.
- Aren't groovy codes superior to scripted cards? (In regards to AI hinting for permanent activations)
Is the aim to get all cards into scripts?
Is it preferable to have all 'def = ' in groovy codes in the main program? (for example niche permanent filters), or is it better to keep them on the specific cards?
I'm always willing to get more stuff scriptable if it can stand up against a groovy version

Or incorporating the script card definitions into groovy, so only one file is needed.
-
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 » 15 Feb 2014, 13:59
Groovy code is much more flexible compared to scripts, the downside is they are longer, harder to write and debug.ShawnieBoy wrote:Aren't groovy codes superior to scripted cards? (In regards to AI hinting for permanent activations)
For me, the ideal is to just paste in the rules text directly in the card script. Scripts are an intermediate step, they help to reduce repetitions and lower the barrier of entry for adding cards.ShawnieBoy wrote:Is the aim to get all cards into scripts?
If it applies to only one card, better to keep in the card's groovy script.ShawnieBoy wrote:Is it preferable to have all 'def = ' in groovy codes in the main program? (for example niche permanent filters), or is it better to keep them on the specific cards?
-
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 » 15 Feb 2014, 15:28

Trostani_s_Summoner.txt
- Code: Select all
name=Trostani's Summoner
url=http://magiccards.info/dgm/en/110.html
image=http://magiccards.info/scans/en/dgm/110.jpg
value=3.773
rarity=U
type=Creature
subtype=Elf,Shaman
cost=5{G}{W}
pt=1/1
timing=main
requires_groovy_code
- Code: Select all
[
new MagicWhenComesIntoPlayTrigger() {
@Override
public MagicEvent executeTrigger(
final MagicGame game,
final MagicPermanent permanent,
final MagicPayedCost payedCost) {
return new MagicEvent(
permanent,
this,
"PN puts a 2/2 white Knight creature token with vigilance, "+
"a 3/3 green Centaur creature token, and "+
"a 4/4 green Rhino creature token with trample onto the battlefield."
)
}
@Override
public void executeEvent(final MagicGame game, final MagicEvent event) {
game.doAction(new MagicPlayTokenAction(
event.getPlayer(),
TokenCardDefinitions.get("2/2 white Knight creature token with vigilance")
));
game.doAction(new MagicPlayTokenAction(
event.getPlayer(),
TokenCardDefinitions.get("3/3 green Centaur creature token")
));
game.doAction(new MagicPlayTokenAction(
event.getPlayer(),
TokenCardDefinitions.get("4/4 green Rhino creature token with trample")
));
}
}
]
-
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 ShawnieBoy » 16 Feb 2014, 05:03
I have another couple of questions (Sorry!)
Is it possible to add MagicConditions to SpellCardEvents? (ie. cast this spell only if...)
Is it possible to determine the amount of life an opponent has lost 'this turn' - I can see a WasDealtDamage MagicPlayerState flag, but nothing more specific.
Thanks
Is it possible to add MagicConditions to SpellCardEvents? (ie. cast this spell only if...)
Is it possible to determine the amount of life an opponent has lost 'this turn' - I can see a WasDealtDamage MagicPlayerState flag, but nothing more specific.
Thanks

-
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 » 16 Feb 2014, 05:30
Questions are good, keep em coming.ShawnieBoy wrote:I have another couple of questions (Sorry!)
Not to SpellCardEvents, those are for representing the effect of a spell. There can be conditions to MagicCardActivation, which is the card counter part of MagicPermanentActivation. MagicCardActivation is the basis for the implementation of bloodrush, cycling, and normal casting of cards from hand (handled by MagicCardActivation itself).ShawnieBoy wrote:Is it possible to add MagicConditions to SpellCardEvents? (ie. cast this spell only if...)
Every card is automatically given a standard MagicCardActivation for casting it by paying the mana cost.
Cards that have additional MagicCardActivation include Force of Will and Lightning Reflexes.
No.ShawnieBoy wrote:Is it possible to determine the amount of life an opponent has lost 'this turn' - I can see a WasDealtDamage MagicPlayerState flag, but nothing more specific.
-
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 » 16 Feb 2014, 05:45
tried to submit this script to firemind.ch, but somehow this card is not recognized. i think this would be in Mike's Authority, maybe.
Anyway here it is

Karametra__God_of_Harvests.txt
Anyway here it is

Karametra__God_of_Harvests.txt
- Code: Select all
name=Karametra, God of Harvests
url=http://magiccards.info/bng/en/148.html
image=http://magiccards.info/scans/en/bng/148.jpg
value=3.331
rarity=M
type=Legendary,Enchantment,Creature
subtype=God
cost={3}{G}{W}
pt=6/7
ability=indestructible
timing=main
requires_groovy_code
- Code: Select all
[
new MagicStatic(MagicLayer.Type) {
@Override
public int getTypeFlags(final MagicPermanent permanent,final int flags) {
return flags & ~MagicType.Creature.getMask();
}
@Override
public void modSubTypeFlags(final MagicPermanent permanent,final Set<MagicSubType> flags) {
flags.remove(MagicSubType.God);
}
@Override
public boolean condition(final MagicGame game,final MagicPermanent source,final MagicPermanent target) {
return source.getController().getDevotion(MagicColor.Green) + source.getController().getDevotion(MagicColor.White)< 7;
}
},
new MagicWhenOtherSpellIsCastTrigger() {
@Override
public MagicEvent executeTrigger(final MagicGame game,final MagicPermanent permanent,final MagicCardOnStack spell) {
return spell.isFriend(permanent) && spell.hasType(MagicType.Creature) ?
new MagicEvent(
cardOnStack,
this,
"PN searches his or her library for a Forest or Plains card and put that card onto the battlefield tapped. Then shuffle PN's library."
):
MagicEvent.NONE;
}
@Override
public void executeEvent(final MagicGame game, final MagicEvent event) {
game.addEvent(new MagicSearchOntoBattlefieldEvent(
event,
MagicTargetChoice.FOREST_PLAINS_CARD_FROM_LIBRARY,
MagicPlayMod.TAPPED
));
}
}
]
-
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 » 16 Feb 2014, 06:00
Nice work! This is the first two color God to be added, https://code.google.com/p/magarena/sour ... bd4b134f1b
Fixed a couple of bugs in the groovy script, the corrected version is below.
Changes:
1) correct calculation of devotion, hybrid mana cost should be counted once only
2) first arg to MagicEvent should be spell instead of cardOnStack
3) should be MagicTargetChoice.FOREST_OR_PLAINS_CARD_FROM_LIBRARY instead of MagicTargetChoice.FOREST_PLAINS_CARD_FROM_LIBRARY
Fixed a couple of bugs in the groovy script, the corrected version is below.
Changes:
1) correct calculation of devotion, hybrid mana cost should be counted once only
2) first arg to MagicEvent should be spell instead of cardOnStack
3) should be MagicTargetChoice.FOREST_OR_PLAINS_CARD_FROM_LIBRARY instead of MagicTargetChoice.FOREST_PLAINS_CARD_FROM_LIBRARY
- Code: Select all
[
new MagicStatic(MagicLayer.Type) {
@Override
public int getTypeFlags(final MagicPermanent permanent,final int flags) {
return flags & ~MagicType.Creature.getMask();
}
@Override
public void modSubTypeFlags(final MagicPermanent permanent,final Set<MagicSubType> flags) {
flags.remove(MagicSubType.God);
}
@Override
public boolean condition(final MagicGame game,final MagicPermanent source,final MagicPermanent target) {
return source.getController().getDevotion(MagicColor.Green, MagicColor.White) < 7;
}
},
new MagicWhenOtherSpellIsCastTrigger() {
@Override
public MagicEvent executeTrigger(final MagicGame game,final MagicPermanent permanent,final MagicCardOnStack spell) {
return spell.isFriend(permanent) && spell.hasType(MagicType.Creature) ?
new MagicEvent(
spell,
this,
"PN searches his or her library for a Forest or Plains card and put that card onto the battlefield tapped. Then shuffle PN's library."
):
MagicEvent.NONE;
}
@Override
public void executeEvent(final MagicGame game, final MagicEvent event) {
game.addEvent(new MagicSearchOntoBattlefieldEvent(
event,
MagicTargetChoice.FOREST_OR_PLAINS_CARD_FROM_LIBRARY,
MagicPlayMod.TAPPED
));
}
}
]
-
melvin - AI Programmer
- Posts: 1062
- Joined: 21 Mar 2010, 12:26
- Location: Singapore
- Has thanked: 36 times
- Been thanked: 459 times
Who is online
Users browsing this forum: No registered users and 0 guests