Adding new cards with Groovy
by ubeefx
Moderators: ubeefx, beholder, melvin, ShawnieBoy, Lodici, CCGHQ Admins
Re: Adding new cards with Groovy
by melvin » 23 Sep 2014, 12:51
Agree, running untrusted code safely is tough. In that case, does it still make sense to merge the changeset in your repo for running card scripts?
-
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 mike » 23 Sep 2014, 14:01
I can still check scripts that run without groovy. The changeset also implements error reporting on firemind which should help debug duels through the web interface.
In short: yes, a merge still makes sense.
In short: yes, a merge still makes sense.
Re: Adding new cards with Groovy
by melvin » 24 Sep 2014, 00:53
Sure, the changeset is merged. I also pushed a small fix to make the code more idiomatic in https://code.google.com/p/magarena/sour ... c69078a89a
-
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 PalladiaMors » 24 Sep 2014, 20:24
Guys, I can't really follow the conversation here, but rather than programming ways to automatically detect if a script works, why don't you just include a warning for people in the submissions page, something like "Before submitting a script, make sure you playtest it to see if it works correctly. If you don't know how to do that, check the Magarena forums for information". In my very humble opinion, that looks simpler and might wield good results...
- PalladiaMors
- Posts: 343
- Joined: 12 Jul 2014, 17:40
- Has thanked: 36 times
- Been thanked: 22 times
Re: Adding new cards with Groovy
by hong yie » 25 Sep 2014, 01:35
can't submit to firemind.ch,
so i put it here.
Gorgon_Recluse.txt
so i put it here.
Gorgon_Recluse.txt
- Code: Select all
name=Gorgon Recluse
image=http://mtgimage.com/card/gorgon%20recluse.jpg
value=2.500
rarity=C
type=Creature
subtype=Gorgon
cost={3}{B}{B}
pt=2/4
ability=Madness {B}{B}
timing=main
requires_groovy_code=Deathgazer
oracle=Whenever Gorgon Recluse blocks or becomes blocked by a nonblack creature, destroy that creature at end of combat. Madness {B}{B}
- Code: Select all
name=Siege Rhino
image=http://magiccards.info/scans/en/ktk/200.jpg
value=2.500
rarity=R
type=Creature
subtype=Rhino
cost={1}{W}{B}{G}
pt=4/5
ability=Trample; When SN enters the battlefield, each opponent loses 3 life and you gain 3 life.
timing=main
oracle=Trample. When Siege Rhino enters the battlefield, each opponent loses 3 life and you gain 3 life.
-
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 » 25 Sep 2014, 05:12
Thanks, added Gorgon Recluse in https://code.google.com/p/magarena/sour ... 095697e769
Siege Rhino's effect can't be parsed as is, you'll get an error when the game loads it. It needs to be rewritten as multiple effects separated by ~, i.e. "When SN enters the battlefield, each opponent loses 3 life.~You gain 3 life." See https://code.google.com/p/magarena/sour ... 07cd09f48a
Siege Rhino's effect can't be parsed as is, you'll get an error when the game loads it. It needs to be rewritten as multiple effects separated by ~, i.e. "When SN enters the battlefield, each opponent loses 3 life.~You gain 3 life." See https://code.google.com/p/magarena/sour ... 07cd09f48a
-
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 » 23 Oct 2014, 18:05
I was trying to add Doran, the Siege Tower, and everything is smooth (no crashes, the game runs fine) except it doesn't work...
edit: at first I tried with MagicTrigger.REPLACE_DAMAGE, but there was no difference
- Code: Select all
[
new MagicIfDamageWouldBeDealtTrigger(MagicTrigger.INCREASE_DAMAGE) {
@Override
public MagicEvent executeTrigger(final MagicGame game,final MagicPermanent permanent,final MagicDamage damage) {
final MagicSource source = damage.getSource();
if (damage.isCombat() && source.isCreature()) {
// Generates no event or action.
damage.setAmount(source.getCardDefinition().getCardToughness());
}
return MagicEvent.NONE;
}
}
]
edit: at first I tried with MagicTrigger.REPLACE_DAMAGE, but there was no difference
- jerichopumpkin
- Posts: 212
- Joined: 12 Sep 2013, 11:21
- Has thanked: 19 times
- Been thanked: 13 times
Re: Adding new cards with Groovy
by mike » 23 Oct 2014, 19:51
I took this as an opportunity to explore the magarena source a little.someone can help me with this one? I don't see what I'm doing wrong...
Unfortunately my conclusion is that there is no easy way to do this.
In MagicCombatDamageAction.java on line 74 I found this
- Code: Select all
if (power>0 && !attacker.hasState(MagicPermanentState.NoCombatDamage))
If I might propose a solution for this: How about replacing power=attacker.getPower() with power=attacker.getCombatPower() which is by default getPower but may be overrwritten for cases like this? This is assuming that attacker.getPower may be overwritten from within the groovy script.
Re: Adding new cards with Groovy
by jerichopumpkin » 23 Oct 2014, 21:52
I took a quick glance myself after reading this, and also on line 61 the same check is done for blockers.mike wrote:
In MagicCombatDamageAction.java on line 74 I found thisWhich means a MagicDealDamageAction is never created and hence no MagicIfDamageWouldBeDealtTrigger will ever be invoked.
- Code: Select all
if (power>0 && !attacker.hasState(MagicPermanentState.NoCombatDamage))
If I might propose a solution for this: How about replacing power=attacker.getPower() with power=attacker.getCombatPower() which is by default getPower but may be overrwritten for cases like this? This is assuming that attacker.getPower may be overwritten from within the groovy script.
I thought the calculations to distribute damage where done after the trigger, but I was dead wrong (thinking about it, it should have been obvious from the start).
Not sure about your idea, there should also be a new MagicStatic to change the value returned by getCombatPower().
For now I will move Doran back to the missing folder, and see if I can put togheter some other cards
- 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 » 24 Oct 2014, 02:29
The checks are there for rule 119.8
Adding getCombatPower and a MagicStatic to modify the combat power value is one possible way, but introduces additional complexity such as additional state in MagicPermanent for combat power which would have to be initialized and managed properly. What others cards would be enabled from such a feature besides Doran?119.8. If a source would deal 0 damage, it does not deal damage at all. That means abilities that trigger on damage being dealt won’t trigger. It also means that replacement effects that would increase the damage dealt by that source, or would have that source deal that damage to a different object or player, have no event to replace, so they have no effect.
-
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 » 24 Oct 2014, 06:58
I fear the answer is: "none". That's a shame, I really love Doran, but it doesn't make sense to add all this code for a single card.melvin wrote:The checks are there for rule 119.8Adding getCombatPower and a MagicStatic to modify the combat power value is one possible way, but introduces additional complexity such as additional state in MagicPermanent for combat power which would have to be initialized and managed properly. What others cards would be enabled from such a feature besides Doran?119.8. If a source would deal 0 damage, it does not deal damage at all. That means abilities that trigger on damage being dealt won’t trigger. It also means that replacement effects that would increase the damage dealt by that source, or would have that source deal that damage to a different object or player, have no event to replace, so they have no effect.
- jerichopumpkin
- Posts: 212
- Joined: 12 Sep 2013, 11:21
- Has thanked: 19 times
- Been thanked: 13 times
Re: Adding new cards with Groovy
by hong yie » 24 Oct 2014, 07:27
it does make sense if we want to achieve 100% playable cards in MtG. Just put it at lower priority.I fear the answer is: "none". That's a shame, I really love Doran, but it doesn't make sense to add all this code for a single card.
-
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 Nov 2014, 01:53
Magarena/scripts/Gargantuan_Gorilla.txt
- Code: Select all
name=Gargantuan Gorilla
image=http://mtgimage.com/card/gargantuan%20gorilla.jpg
value=2.500
rarity=R
type=Creature
subtype=Ape
cost={4}{G}{G}{G}
pt=7/7
timing=main
requires_groovy_code
oracle=At the beginning of your upkeep, you may sacrifice a Forest. If you sacrifice a snow Forest this way, Gargantuan Gorilla gains trample until end of turn. If you don't sacrifice a Forest, sacrifice Gargantuan Gorilla and it deals 7 damage to you. {T}: Gargantuan Gorilla deals damage equal to its power to another target creature. That creature deals damage equal to its power to Gargantuan Gorilla.
- Code: Select all
def SAC_ACTION = {
final MagicGame game, final MagicEvent event ->
event.processTargetPermanent(game, {
game.doAction(new MagicSacrificeAction(it));
if (it.hasType(MagicType.Snow)) {
game.doAction(new MagicGainAbilityAction(event.getPermanent(),MagicAbility.Trample));
}
})
}
[
new MagicAtYourUpkeepTrigger() {
@Override
public MagicEvent executeTrigger(final MagicGame game,final MagicPermanent permanent,final MagicPlayer upkeepPlayer) {
return new MagicEvent(
permanent,
new MagicMayChoice("Sacrifice a Forest?"),
this,
"PN may\$ sacrifice a Forest. " +
"If PN sacrifices a snow Forest this way, SN gains trample until end of turn. " +
"If PN doesn't sacrifice a Forest, sacrifice SN and it deals 7 damage to you."
);
}
@Override
public void executeEvent(final MagicGame game, final MagicEvent event) {
final MagicPermanent SN = event.getPermanent();
final MagicPlayer PN = event.getPlayer();
final MagicEvent sac = new MagicEvent(
SN,
PN,
MagicTargetChoice.SACRIFICE_FOREST,
MagicSacrificeTargetPicker.create(),
SAC_ACTION,
"Choose a Forest to sacrifice\$."
);
if (event.isYes() && PN.controlsPermanent(MagicSubType.Forest)) {
game.addEvent(sac);
} else {
game.doAction(new MagicSacrificeAction(SN));
game.doAction(new MagicDealDamageAction(SN, PN, 7));
}
}
},
new MagicPermanentActivation(
new MagicActivationHints(MagicTiming.Removal),
"Damage"
) {
@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.NegOther("target creature", source),
new MagicDamageTargetPicker(source.getPower()),
this,
"SN deals damage equal to its power to another target creature. " +
"That creature deals damage equal to its power to SN."
);
}
@Override
public void executeEvent(final MagicGame game, final MagicEvent event) {
event.processTargetPermanent(game, {
game.doAction(new MagicDealDamageAction(
event.getPermanent(),
it,
event.getPermanent().getPower()
));
game.doAction(new MagicDealDamageAction(
it,
event.getPermanent(),
it.getPower()
));
});
}
}
]
-
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 PalladiaMors » 02 Nov 2014, 14:10
Trying to do Ebon Praetor, but I can't find the name of the "activate only once each turn" condition. I know it's in, there's plenty of cards with it, just not in groovy form. Can someone please tell me the right name?
- Code: Select all
[
new MagicPermanentActivation(
[MagicCondition.YOUR_UPKEEP_CONDITION, MagicCondition.NO_MORE_THAN_ONCE_CONDITION],
new MagicActivationHints(MagicTiming.Pump),
"Sacrifice"
) {
@Override
public Iterable<MagicEvent> getCostEvent(final MagicPermanent source) {
return [new MagicSacrificePermanentEvent(source,MagicTargetChoice.SACRIFICE_CREATURE)];
}
@Override
public MagicEvent getPermanentEvent(final MagicPermanent source, final MagicPayedCost payedCost) {
return new MagicEvent(
source,
payedCost.getTarget(),
this,
"Remove a -2/-2 counter from SN. " +
"If the sacrificed creature was a Thrull, put a +1/+0 counter on SN."
);
}
@Override
public void executeEvent(final MagicGame game, final MagicEvent event) {
final MagicPermanent sacrificed = event.getRefPermanent();
new MagicRemoveCounterEvent(
event.getPermanent(),
MagicCounterType.MinusTwo,
1
);
if (sacrificed.hasSubType(MagicSubType.Thrull)) {
game.doAction(new MagicChangeCountersAction(
event.getPermanent(),
MagicCounterType.PlusOnePlusZero,
1
));
}
}
}
]
- PalladiaMors
- Posts: 343
- Joined: 12 Jul 2014, 17:40
- Has thanked: 36 times
- Been thanked: 22 times
Re: Adding new cards with Groovy
by melvin » 03 Nov 2014, 00:35
Add "new MagicPlayAbilityEvent(source)" to getCostEvent for activate at most once per turn.
For example,
For example,
- Code: Select all
@Override
public Iterable<MagicEvent> getCostEvent(final MagicPermanent source) {
return [
new MagicSacrificePermanentEvent(source,MagicTargetChoice.SACRIFICE_CREATURE),
new MagicPlayAbilityEvent(source)
];
}
-
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 24 guests