It is currently 19 Jul 2025, 05:17
   
Text Size

Adding new cards with Groovy

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

Re: Adding new cards with Groovy

Postby melvin » 08 Feb 2014, 08:00

ShawnieBoy wrote:Hmm, I've tried that, but the computer has a habit of selecting 'Yes' but then not paying the mana.
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.
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 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 :(
User avatar
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

Postby 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
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
Deus_of_Calamity.groovy
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()));
        }
    }
]
Any hint?
jerichopumpkin
 
Posts: 212
Joined: 12 Sep 2013, 11:21
Has thanked: 19 times
Been thanked: 13 times

Re: Adding new cards with Groovy

Postby melvin » 11 Feb 2014, 02:05

jerichopumpkin wrote:I've been trying to add Deus of Calamity, but something is not right.
1)
Code: Select all
return (damage.getSource() == permanent &&
                    permanent.isOpponent(damage.getTarget()) &&
               damage.getAmount() >= 6) ?
            return new MagicEvent(
Extra return. Remove "return" before "new"

2)
Code: Select all
new MagicEvent(
    source,
    TARGET_LAND_YOUR_OPPONENT_CONTROLS,
    MagicDestroyTargetPicker.Destroy,
    this,
    "Destroy target land\$."
):
The "source" variable used as the first argument doesn't exist, you probably mean "permanent"
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 jerichopumpkin » 11 Feb 2014, 07:39

:oops: silly me, I should do the scripting before dinner, instead of before bedtime!
jerichopumpkin
 
Posts: 212
Joined: 12 Sep 2013, 11:21
Has thanked: 19 times
Been thanked: 13 times

Re: Adding new cards with Groovy

Postby melvin » 11 Feb 2014, 12:31

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
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.
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 jerichopumpkin » 11 Feb 2014, 17:02

It seems to enter an infinite loop. Magarena is just stuck here:
prnt-scrn-mag.jpg
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:
crash.png
jerichopumpkin
 
Posts: 212
Joined: 12 Sep 2013, 11:21
Has thanked: 19 times
Been thanked: 13 times

Re: Adding new cards with Groovy

Postby ShawnieBoy » 11 Feb 2014, 19:24

This has already been fixed for 1.47 - try using that one :)
User avatar
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

Postby ShawnieBoy » 13 Feb 2014, 18:06

While trundling through groovy codes, I've been beginning to wonder:

    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.
User avatar
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

Postby melvin » 15 Feb 2014, 13:59

ShawnieBoy wrote:Aren't groovy codes superior to scripted cards? (In regards to AI hinting for permanent activations)
Groovy code is much more flexible compared to scripts, the downside is they are longer, harder to write and debug.

ShawnieBoy wrote:Is the aim to get all cards into scripts?
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 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?
If it applies to only one card, better to keep in the card's groovy script.
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 hong yie » 15 Feb 2014, 15:28

Image

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
Trostani_s_Summoner.groovy
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")                              
            ));
      }
    }
]
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 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 :D
User avatar
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

Postby melvin » 16 Feb 2014, 05:30

ShawnieBoy wrote:I have another couple of questions (Sorry!)
Questions are good, keep em coming.

ShawnieBoy wrote:Is it possible to add MagicConditions to SpellCardEvents? (ie. cast this spell only if...)
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).

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.

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.
No.
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 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

Image
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
Karametra__God_of_Harvests.groovy
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
            ));
        }
    }
]
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 » 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
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
            ));
        }
    }
]
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 6 guests

Main Menu

User Menu

Our Partners


Who is online

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

Login Form