Card Contributions
by ubeefx
Moderators: ubeefx, beholder, melvin, ShawnieBoy, Lodici, CCGHQ Admins
Re: Card Contributions
by melvin » 15 Mar 2015, 02:21
Wrong usage of executeModalEvent, it was created to replace the isMode checks.
- Code: Select all
public void executeEvent(final MagicGame game, final MagicEvent event) {
if (event.isKicked()) {
game.addEvent(EFFECT1.getEvent(event.getSource()));
game.addEvent(EFFECT2.getEvent(event.getSource()));
} else {
event.executeModalEvent(game, EFFECT1, EFFECT2);
}
}
-
melvin - AI Programmer
- Posts: 1062
- Joined: 21 Mar 2010, 12:26
- Location: Singapore
- Has thanked: 36 times
- Been thanked: 459 times
Re: Card Contributions
by melvin » 15 Mar 2015, 02:31
Not exactly, with ShawnieBoy's suggestion of creating different choices for entwine and not entwine case, in the entwine case the choice can be MagicTargetChoice if only one of the options has a target.PalladiaMors wrote:The other issue is that this way of doing entwine can only be used for untargeted cards; cards that require a target won't be viable because if the kicker mode is chosen it won't be able to get a target.
-
melvin - AI Programmer
- Posts: 1062
- Joined: 21 Mar 2010, 12:26
- Location: Singapore
- Has thanked: 36 times
- Been thanked: 459 times
Re: Card Contributions
by ShawnieBoy » 15 Mar 2015, 04:51
Ahh yes, of course - thanks for that.melvin wrote:Wrong usage of executeModalEvent, it was created to replace the isMode checks.
- Code: Select all
public void executeEvent(final MagicGame game, final MagicEvent event) {
if (event.isKicked()) {
game.addEvent(EFFECT1.getEvent(event.getSource()));
game.addEvent(EFFECT2.getEvent(event.getSource()));
} else {
event.executeModalEvent(game, EFFECT1, EFFECT2);
}
}
-
ShawnieBoy - Programmer
- Posts: 601
- Joined: 02 Apr 2012, 22:42
- Location: UK
- Has thanked: 80 times
- Been thanked: 50 times
Re: Card Contributions
by ShawnieBoy » 15 Mar 2015, 05:10
Back to basics works best
Here's the whole thing.
Here's the whole thing.
- Code: Select all
def EFFECT1 = MagicRuleEventAction.create("Creatures you control get +1/+1 until end of turn.");
def EFFECT2 = MagicRuleEventAction.create("Untap all creatures you control.");
def CARDTEXT = "Choose one\$ — • Creatures you control get +1/+1 until end of turn." +
" • Untap all creatures you control. " +
"Choose both if you paid the entwine cost.";
[
new MagicSpellCardEvent() {
@Override
public MagicEvent getEvent(final MagicCardOnStack cardOnStack, final MagicPayedCost payedCost) {
return payedCost.isKicked() ?
new MagicEvent(
cardOnStack,
this,
CARDTEXT
):
new MagicEvent(
cardOnStack,
new MagicOrChoice(
MagicChoice.NONE,
MagicChoice.NONE
),
this,
CARDTEXT
);
}
@Override
public void executeEvent(final MagicGame game, final MagicEvent event) {
if (event.isKicked()) {
game.addEvent((EFFECT1).getEvent(event.getSource()));
game.addEvent((EFFECT2).getEvent(event.getSource()));
} else if (event.isMode(1)) {
game.addEvent((EFFECT1).getEvent(event.getSource()));
} else if (event.isMode(2)) {
game.addEvent((EFFECT2).getEvent(event.getSource()));
}
}
}
]
-
ShawnieBoy - Programmer
- Posts: 601
- Joined: 02 Apr 2012, 22:42
- Location: UK
- Has thanked: 80 times
- Been thanked: 50 times
Re: Card Contributions
by melvin » 15 Mar 2015, 06:05
There is a bug in my earlier example, addEvent should not be used, especially if we want to support effects with target as it requires the choice to be made again. It should be executeEvent, as seen from executeModalEvent the correct way to call it should be:
For the entwine, case I created executeAllEvent.
The combined logic should be:
- Code: Select all
sourceEvents[i].getEvent(getSource()).executeEvent(game, getChosen());
For the entwine, case I created executeAllEvent.
The combined logic should be:
- Code: Select all
if (event.isKicked()) {
event.executeAllEvents(game, EFFECT1, EFFECT2);
} else {
event.executeModalEvent(game, EFFECT1, EFFECT2);
}
-
melvin - AI Programmer
- Posts: 1062
- Joined: 21 Mar 2010, 12:26
- Location: Singapore
- Has thanked: 36 times
- Been thanked: 459 times
Re: Card Contributions
by melvin » 15 Mar 2015, 06:38
Example with one option having a target: see viewtopic.php?f=82&t=10323&p=175091#p175091
-
melvin - AI Programmer
- Posts: 1062
- Joined: 21 Mar 2010, 12:26
- Location: Singapore
- Has thanked: 36 times
- Been thanked: 459 times
Re: Card Contributions
by melvin » 15 Mar 2015, 09:29
Found a way to do it as card script. Updated examples on "Adding new cards with Groovy" script.
Groovy script archived at https://github.com/magarena/magarena/bl ... ant.groovy and https://github.com/magarena/magarena/bl ... Kha.groovy
Groovy script archived at https://github.com/magarena/magarena/bl ... ant.groovy and https://github.com/magarena/magarena/bl ... Kha.groovy
-
melvin - AI Programmer
- Posts: 1062
- Joined: 21 Mar 2010, 12:26
- Location: Singapore
- Has thanked: 36 times
- Been thanked: 459 times
Re: Card Contributions
by PalladiaMors » 15 Mar 2015, 15:51
I'll give the remaining ones a try as soon as I can, but I have a doubt: can the cards that can't use RuleEventAction be done with the isMode checks? Or does that no longer work correctly? I'm pretty sure I'm capable of doing those with the mode checks, but I've no idea how to do them with executeModalEvent if they can't use RuleEventAction.
The last ~30 days have been great concerning implementation of new mechanics. Modal spells, Affinity, Entwine, non-mana cumulative upkeeps (that was already possible, but none of them had been previously done). That's well over 100 cards that I previously thought not possible yet. Way to go! Also, a huge amount of the recently implemented cards are instants, so they've caught up a bit with creatures, which hopefully should help balance the Firemind metagame a bit. It was also a very "Mirrodin" month, with affinity and entwine. With the rest of the Entwine cards and particularly Tooth and Nail, pretty much every competitive deck from Mirrodin Block Constructed will have >90% of its cards available.
Edit: did Promise of Power with isMode, tested each of the 3 modes and it looks like it works alright (besides the fact that you can't choose the order of effects in the entwined version, so I chose to draw first in order to get the Demon bigger). Looks like it works ok this way, so I'll try to do the ones I can like that.
Edit2: Firemind down today, so posting the cards here.
The last ~30 days have been great concerning implementation of new mechanics. Modal spells, Affinity, Entwine, non-mana cumulative upkeeps (that was already possible, but none of them had been previously done). That's well over 100 cards that I previously thought not possible yet. Way to go! Also, a huge amount of the recently implemented cards are instants, so they've caught up a bit with creatures, which hopefully should help balance the Firemind metagame a bit. It was also a very "Mirrodin" month, with affinity and entwine. With the rest of the Entwine cards and particularly Tooth and Nail, pretty much every competitive deck from Mirrodin Block Constructed will have >90% of its cards available.
Edit: did Promise of Power with isMode, tested each of the 3 modes and it looks like it works alright (besides the fact that you can't choose the order of effects in the entwined version, so I chose to draw first in order to get the Demon bigger). Looks like it works ok this way, so I'll try to do the ones I can like that.
Edit2: Firemind down today, so posting the cards here.
- Code: Select all
name=black Demon creature token with flying
token=Demon
image=http://gatherer.wizards.com/Handlers/Image.ashx?multiverseid=197936&type=card
value=2
type=Creature
subtype=Demon
color=b
ability=flying
- Code: Select all
name=Promise of Power
image=http://mtgimage.com/card/promise%20of%20power.jpg
value=2.500
rarity=R
type=Sorcery
cost={2}{B}{B}{B}
ability=Entwine {4}
timing=main
requires_groovy_code
oracle=Choose one — • You draw five cards and you lose 5 life. • Put an X/X black Demon creature token with flying onto the battlefield, where X is the number of cards in your hand as the token enters the battlefield. Entwine {4}
- Code: Select all
def TEXT1 = "You draw five cards and you lose 5 life."
def TEXT2 = "Put an X/X black Demon creature token with flying onto the battlefield, "+
"where X is the number of cards in your hand as the token enters the battlefield."
[
new MagicSpellCardEvent() {
@Override
public MagicEvent getEvent(final MagicCardOnStack cardOnStack, final MagicPayedCost payedCost) {
return new MagicEvent(
cardOnStack,
payedCost.isKicked() ?
MagicChoice.NONE :
new MagicOrChoice(
MagicChoice.NONE,
MagicChoice.NONE
),
this,
payedCost.isKicked() ?
"You draw five cards and you lose 5 life. "+
"Put an X/X black Demon creature token with flying onto the battlefield, "+
"where X is the number of cards in your hand as the token enters the battlefield." :
"Choose one\$ — • " + TEXT1 + " • " + TEXT2 + "\$"
);
}
@Override
public void executeEvent(final MagicGame game, final MagicEvent event) {
if (event.isKicked()) {
game.doAction(new MagicDrawAction(event.getPlayer(),5));
game.doAction(new MagicChangeLifeAction(event.getPlayer(), -5));
final int x = event.getPlayer().getHandSize();
game.doAction(new MagicPlayTokenAction(event.getPlayer(), MagicCardDefinition.create({
it.setName("Demon");
it.setFullName("black Demon creature token with flying");
it.setPowerToughness(x, x);
it.setColors("b");
it.addSubType(MagicSubType.Demon);
it.addType(MagicType.Creature);
it.setToken();
it.setValue(x);
})));
} else if (event.isMode(1)) {
game.addEvent(MagicRuleEventAction.create("You draw five cards and you lose 5 life.").getEvent(event.getSource()));
} else if (event.isMode(2)) {
final int x = event.getPlayer().getHandSize();
game.doAction(new MagicPlayTokenAction(event.getPlayer(), MagicCardDefinition.create({
it.setName("Demon");
it.setFullName("black Demon creature token with flying");
it.setPowerToughness(x, x);
it.setColors("b");
it.addSubType(MagicSubType.Demon);
it.addType(MagicType.Creature);
it.setToken();
it.setValue(x);
})));
}
}
}
]
- Code: Select all
name=Rude Awakening
image=http://mtgimage.com/card/rude%20awakening.jpg
value=2.500
rarity=R
type=Sorcery
cost={4}{G}
ability=Entwine {2}{G}
timing=main
requires_groovy_code
oracle=Choose one — • Untap all lands you control. • Until end of turn, lands you control become 2/2 creatures that are still lands. Entwine {2}{G}
- Code: Select all
def PT = new MagicStatic(MagicLayer.SetPT, MagicStatic.UntilEOT) {
@Override
public void modPowerToughness(final MagicPermanent source,final MagicPermanent permanent,final MagicPowerToughness pt) {
pt.set(2,2);
}
};
def ST = new MagicStatic(MagicLayer.Type, MagicStatic.UntilEOT) {
@Override
public int getTypeFlags(final MagicPermanent permanent,final int flags) {
return flags|MagicType.Creature.getMask();
}
};
def TEXT1 = "Untap all lands you control."
def TEXT2 = "Until end of turn, lands you control become 2/2 creatures that are still lands."
[
new MagicSpellCardEvent() {
@Override
public MagicEvent getEvent(final MagicCardOnStack cardOnStack, final MagicPayedCost payedCost) {
return new MagicEvent(
cardOnStack,
payedCost.isKicked() ?
MagicChoice.NONE :
new MagicOrChoice(
MagicChoice.NONE,
MagicChoice.NONE
),
this,
payedCost.isKicked() ?
"Untap all lands you control. "+
"Until end of turn, lands you control become 2/2 creatures that are still lands." :
"Choose one\$ — • " + TEXT1 + " • " + TEXT2 + "\$"
);
}
@Override
public void executeEvent(final MagicGame game, final MagicEvent event) {
if (event.isKicked()) {
final Collection<MagicPermanent> targets = event.getPlayer().filterPermanents(MagicTargetFilterFactory.LAND_YOU_CONTROL);
for (final MagicPermanent target : targets) {
game.doAction(new MagicUntapAction(target));
game.doAction(new MagicBecomesCreatureAction(target,PT,ST));
}
} else if (event.isMode(1)) {
final Collection<MagicPermanent> targets = event.getPlayer().filterPermanents(MagicTargetFilterFactory.LAND_YOU_CONTROL);
for (final MagicPermanent target : targets) {
game.doAction(new MagicUntapAction(target));
}
} else if (event.isMode(2)) {
final Collection<MagicPermanent> targets = event.getPlayer().filterPermanents(MagicTargetFilterFactory.LAND_YOU_CONTROL);
for (final MagicPermanent target : targets) {
game.doAction(new MagicBecomesCreatureAction(target,PT,ST));
}
}
}
}
]
- Code: Select all
name=Pilgrim of the Fires
image=http://mtgimage.com/card/pilgrim%20of%20the%20fires.jpg
value=2.500
rarity=U
type=Artifact,Creature
subtype=Golem
cost={7}
pt=6/4
ability=First strike; trample
timing=main
oracle=First strike, trample
- Code: Select all
name=Temporal Cascade
image=http://mtgimage.com/card/temporal%20cascade.jpg
value=2.500
rarity=R
type=Sorcery
cost={5}{U}{U}
ability=Entwine {2}
timing=main
requires_groovy_code
oracle=Choose one — • Each player shuffles his or her hand and graveyard into his or her library. • Each player draws seven cards. Entwine {2}
- Code: Select all
def TEXT1 = "Each player shuffles his or her hand and graveyard into his or her library."
def TEXT2 = "Each player draws seven cards."
[
new MagicSpellCardEvent() {
@Override
public MagicEvent getEvent(final MagicCardOnStack cardOnStack, final MagicPayedCost payedCost) {
return new MagicEvent(
cardOnStack,
payedCost.isKicked() ?
MagicChoice.NONE :
new MagicOrChoice(
MagicChoice.NONE,
MagicChoice.NONE
),
this,
payedCost.isKicked() ?
"Each player shuffles his or her hand and graveyard into his or her library. "+
"Each player draws seven cards." :
"Choose one\$ — • " + TEXT1 + " • " + TEXT2 + "\$"
);
}
@Override
public void executeEvent(final MagicGame game, final MagicEvent event) {
if (event.isKicked()) {
for (final MagicPlayer player : game.getAPNAP()) {
final MagicCardList graveyard = new MagicCardList(player.getGraveyard());
final MagicCardList hand = new MagicCardList(player.getHand());
for (final MagicCard card : graveyard) {
game.doAction(new MagicRemoveCardAction(card,MagicLocationType.Graveyard));
game.doAction(new MagicMoveCardAction(card,MagicLocationType.Graveyard,MagicLocationType.OwnersLibrary));
}
for (final MagicCard card : hand) {
game.doAction(new MagicRemoveCardAction(card,MagicLocationType.OwnersHand));
game.doAction(new MagicMoveCardAction(card,MagicLocationType.OwnersHand,MagicLocationType.OwnersLibrary));
}
game.doAction(new MagicDrawAction(player,7));
};
} else if (event.isMode(1)) {
for (final MagicPlayer player : game.getAPNAP()) {
final MagicCardList graveyard = new MagicCardList(player.getGraveyard());
final MagicCardList hand = new MagicCardList(player.getHand());
for (final MagicCard card : graveyard) {
game.doAction(new MagicRemoveCardAction(card,MagicLocationType.Graveyard));
game.doAction(new MagicMoveCardAction(card,MagicLocationType.Graveyard,MagicLocationType.OwnersLibrary));
}
for (final MagicCard card : hand) {
game.doAction(new MagicRemoveCardAction(card,MagicLocationType.OwnersHand));
game.doAction(new MagicMoveCardAction(card,MagicLocationType.OwnersHand,MagicLocationType.OwnersLibrary));
}
}
} else if (event.isMode(2)) {
for (final MagicPlayer player : game.getAPNAP()) {
game.doAction(new MagicDrawAction(player,7));
}
}
}
}
]
- Code: Select all
name=Tooth and Nail
image=http://mtgimage.com/card/tooth%20and%20nail.jpg
value=2.500
rarity=R
type=Sorcery
cost={5}{G}{G}
ability=Entwine {2}
timing=main
requires_groovy_code
oracle=Choose one — • Search your library for up to two creature cards, reveal them, put them into your hand, then shuffle your library. • Put up to two creature cards from your hand onto the battlefield. Entwine {2}
- Code: Select all
def TEXT1 = "Search your library for up to two creature cards, reveal them, put them into your hand, then shuffle your library."
def TEXT2 = "Put up to two creature cards from your hand onto the battlefield."
def choice = new MagicTargetChoice("a creature card from your hand");
[
new MagicSpellCardEvent() {
@Override
public MagicEvent getEvent(final MagicCardOnStack cardOnStack, final MagicPayedCost payedCost) {
return new MagicEvent(
cardOnStack,
payedCost.isKicked() ?
MagicChoice.NONE :
new MagicOrChoice(
MagicChoice.NONE,
MagicChoice.NONE
),
this,
payedCost.isKicked() ?
"Search your library for up to two creature cards, reveal them, put them into your hand, then shuffle your library."+
" Put up to two creature cards from your hand onto the battlefield." :
"Choose one\$ — • " + TEXT1 + " • " + TEXT2 + "\$"
);
}
@Override
public void executeEvent(final MagicGame game, final MagicEvent event) {
if (event.isKicked()) {
final List<MagicCard> choiceList = event.getPlayer().filterCards(MagicTargetFilterFactory.CREATURE_CARD_FROM_LIBRARY);
game.addEvent(new MagicSearchToLocationEvent(
event,
new MagicFromCardListChoice(choiceList, 2, true),
MagicLocationType.OwnersHand
));
game.addEvent(new MagicPutOntoBattlefieldEvent(
event,
new MagicMayChoice(choice)
));
game.addEvent(new MagicPutOntoBattlefieldEvent(
event,
new MagicMayChoice(choice)
));
} else if (event.isMode(1)) {
final List<MagicCard> choiceList = event.getPlayer().filterCards(MagicTargetFilterFactory.CREATURE_CARD_FROM_LIBRARY);
game.addEvent(new MagicSearchToLocationEvent(
event,
new MagicFromCardListChoice(choiceList, 2, true),
MagicLocationType.OwnersHand
));
} else if (event.isMode(2)) {
game.addEvent(new MagicPutOntoBattlefieldEvent(
event,
new MagicMayChoice(choice)
));
game.addEvent(new MagicPutOntoBattlefieldEvent(
event,
new MagicMayChoice(choice)
));
}
}
}
]
- Code: Select all
name=Oblivion Stone
image=http://mtgimage.com/card/oblivion%20stone.jpg
value=2.500
rarity=R
type=Artifact
cost={3}
ability={4}, {T}: Put a fate counter on target permanent.
timing=artifact
requires_groovy_code
oracle={4}, {T}: Put a fate counter on target permanent. {5}, {T}, Sacrifice Oblivion Stone: Destroy each nonland permanent without a fate counter on it, then remove all fate counters from all permanents.
- Code: Select all
def NONLAND_PERMANENT_WITHOUT_FATE_COUNTER = new MagicPermanentFilterImpl() {
public boolean accept(final MagicGame game,final MagicPlayer player,final MagicPermanent target) {
return !target.isLand() && target.getCounters(MagicCounterType.Fade) == 0;
}
};
[
new MagicPermanentActivation(
new MagicActivationHints(MagicTiming.Removal),
"Destroy"
) {
@Override
public Iterable<MagicEvent> getCostEvent(final MagicPermanent source) {
return [
new MagicPayManaCostEvent(source,"{5}"),
new MagicTapEvent(source),
new MagicSacrificeEvent(source)
];
}
@Override
public MagicEvent getPermanentEvent(final MagicPermanent source, final MagicPayedCost payedCost) {
return new MagicEvent(
source,
this,
"Destroy each nonland permanent without a fate counter on it, "+
"then remove all fate counters from all permanents."
);
}
@Override
public void executeEvent(final MagicGame game, final MagicEvent event) {
final Collection<MagicPermanent> targets =
game.filterPermanents(NONLAND_PERMANENT_WITHOUT_FATE_COUNTER);
game.doAction(new MagicDestroyAction(targets));
final List<MagicPermanent> permanents = game.filterPermanents(MagicTargetFilterFactory.PERMANENT);
for (final MagicPermanent permanent : permanents) {
game.doAction(new MagicChangeCountersAction(
permanent,
MagicCounterType.Fate,
permanent.getCounters(MagicCounterType.Fate)
));
}
}
}
]
- PalladiaMors
- Posts: 343
- Joined: 12 Jul 2014, 17:40
- Has thanked: 36 times
- Been thanked: 22 times
Re: Card Contributions
by melvin » 16 Mar 2015, 00:25
You can't choose the order according to 702.41bPalladiaMors wrote:besides the fact that you can't choose the order of effects in the entwined version
Draw before Demon is correct as Draw is mode 1 and Demon is mode 2.702.41b wrote:If the entwine cost was paid, follow the text of each of the
modes in the order written on the card when the spell resolves.
Cards on the forum is rather error prone to integrate, please submit to firemind.ch when it is back up. Thanks.PalladiaMors wrote:Firemind down today, so posting the cards here.
-
melvin - AI Programmer
- Posts: 1062
- Joined: 21 Mar 2010, 12:26
- Location: Singapore
- Has thanked: 36 times
- Been thanked: 459 times
Re: Card Contributions
by PalladiaMors » 19 Mar 2015, 02:24
Gave my first try to a planeswalker, Garruk Relentless / Garruk, the Veil-Cursed. Unfortunately, I'm having problems with the transformation. Normally I'd drop it, but this one was a lot of work, so I though I'd better ask for help.
Edit: Submitted fixes for Worldgorger Dragon, Wormfang Behemoth and Slithermuse. Sorry for not playtesting those better
- Code: Select all
name=Garruk Relentless
image=http://mtgimage.com/card/garruk%20relentless.jpg
value=2.500
rarity=M
type=Planeswalker
subtype=Garruk
cost={3}{G}
ability=loyalty 3
transform=Garruk, the Veil-Cursed
timing=main
requires_groovy_code
oracle=When Garruk Relentless has two or fewer loyalty counters on him, transform him. 0: Garruk Relentless deals 3 damage to target creature. That creature deals damage equal to its power to him. 0: Put a 2/2 green Wolf creature token onto the battlefield.
- Code: Select all
[
new MagicStatic(MagicLayer.Game) {
@Override
public boolean condition(final MagicGame game,final MagicPermanent source,final MagicPermanent target) {
return source.getCounters(MagicCounterType.Loyalty) <= 2;
}
@Override
public void modGame(final MagicPermanent source, final MagicGame game) {
game.doAction(new MagicTransformAction(source));
}
},
new MagicPlaneswalkerActivation(0) {
@Override
public MagicEvent getPermanentEvent(final MagicPermanent source,final MagicPayedCost payedCost) {
return new MagicEvent(
source,
MagicTargetChoice.NEG_TARGET_CREATURE,
this,
"SN deals 3 damage to target creature. That creature deals damage equal to its power to him."
);
}
@Override
public void executeEvent(final MagicGame game, final MagicEvent event) {
event.processTargetPermanent(game, {
game.doAction(new MagicDealDamageAction(event.getSource(),it,3));
game.doAction(new MagicDealDamageAction(it,event.getPermanent(),it.getPower()));
});
}
},
new MagicPlaneswalkerActivation(0) {
@Override
public MagicEvent getPermanentEvent(final MagicPermanent source,final MagicPayedCost payedCost) {
return new MagicEvent(
source,
this,
"Put a 2/2 green Wolf creature token onto the battlefield."
);
}
@Override
public void executeEvent(final MagicGame game, final MagicEvent event) {
game.doAction(new MagicPlayTokenAction(event.getPlayer(),TokenCardDefinitions.get("2/2 green Wolf creature token")));
}
}
]
- Code: Select all
name=Garruk, the Veil-Cursed
image=http://mtgimage.com/card/garruk%2C%20the%20veil-cursed.jpg
value=2.500
rarity=M
type=Planeswalker
subtype=Garruk
color=bg
transform=Garruk Relentless
timing=main
requires_groovy_code
oracle=+1: Put a 1/1 black Wolf creature token with deathtouch onto the battlefield. −1: Sacrifice a creature. If you do, search your library for a creature card, reveal it, put it into your hand, then shuffle your library. −3: Creatures you control gain trample and get +X/+X until end of turn, where X is the number of creature cards in your graveyard.
- Code: Select all
[
new MagicPlaneswalkerActivation(1) {
@Override
public MagicEvent getPermanentEvent(final MagicPermanent source,final MagicPayedCost payedCost) {
return new MagicEvent(
source,
this,
"Put a 1/1 black Wolf creature token with deathtouch onto the battlefield."
);
}
@Override
public void executeEvent(final MagicGame game, final MagicEvent event) {
game.doAction(new MagicPlayTokenAction(event.getPlayer(),TokenCardDefinitions.get("1/1 black Wolf creature token with deathtouch")));
}
},
new MagicPlaneswalkerActivation(-1) {
@Override
public MagicEvent getPermanentEvent(final MagicPermanent source,final MagicPayedCost payedCost) {
return new MagicEvent(
source,
this,
"Sacrifice a creature. If you do, search your library for a creature card, reveal it, put it into your hand, then shuffle your library."
);
}
@Override
public void executeEvent(final MagicGame game, final MagicEvent event) {
final MagicEvent sac = new MagicSacrificePermanentEvent(event.getSource(),event.getPlayer(),MagicTargetChoice.SACRIFICE_CREATURE);
if (sac.isSatisfied()) {
final List<MagicCard> choiceList = event.getPlayer().filterCards(MagicTargetFilterFactory.CREATURE_CARD_FROM_LIBRARY);
game.addEvent(new MagicSearchToLocationEvent(
event,
new MagicFromCardListChoice(choiceList, 1, true),
MagicLocationType.OwnersHand
)); }
}
},
new MagicPlaneswalkerActivation(-3) {
@Override
public MagicEvent getPermanentEvent(final MagicPermanent source,final MagicPayedCost payedCost) {
return new MagicEvent(
source,
this,
"Creatures you control gain trample and get +X/+X until end of turn, where X is the number of creature cards in your graveyard."
);
}
@Override
public void executeEvent(final MagicGame game, final MagicEvent event) {
final int X = game.filterCards(event.getPlayer(), MagicTargetFilterFactory.CREATURE_CARD_FROM_GRAVEYARD).size();
final Collection<MagicPermanent> targets = game.filterPermanents(
event.getPlayer(),
MagicTargetFilterFactory.CREATURE_YOU_CONTROL
);
for (final MagicPermanent target : targets) {
game.doAction(new MagicGainAbilityAction(target, MagicAbility.Trample));
game.doAction(new MagicChangeTurnPTAction(target, X, X)); }
}
}
]
Edit: Submitted fixes for Worldgorger Dragon, Wormfang Behemoth and Slithermuse. Sorry for not playtesting those better
Last edited by PalladiaMors on 19 Mar 2015, 03:16, edited 1 time in total.
- PalladiaMors
- Posts: 343
- Joined: 12 Jul 2014, 17:40
- Has thanked: 36 times
- Been thanked: 22 times
Re: Card Contributions
by melvin » 19 Mar 2015, 03:00
The first ability is a state-triggered ability, so it should be
- Code: Select all
def EFFECT = MagicRuleEventAction.create("Transform SN.");
[
new MagicStatic(MagicLayer.Game) {
@Override
public boolean condition(final MagicGame game,final MagicPermanent source,final MagicPermanent target) {
return source.getCounters(MagicCounterType.Loyalty) <= 2;
}
@Override
public void modGame(final MagicPermanent source, final MagicGame game) {
game.doAction(new MagicPutStateTriggerOnStackAction(
EFFECT.getEvent(source)
));
}
},
...
]
-
melvin - AI Programmer
- Posts: 1062
- Joined: 21 Mar 2010, 12:26
- Location: Singapore
- Has thanked: 36 times
- Been thanked: 459 times
Re: Card Contributions
by PalladiaMors » 19 Mar 2015, 03:11
Now it transforms, but none of Veil-Cursed's abilities can be activated. I admit I currently don't have the pictures, so it's been kind of difficult to playtest properly. Oh and please notice the edit about the fixes above, those 3 cards are currently completely broken. I should really playtest more thoroughly, but sometimes I don't have enough time, I'm sorry about that.
Edit: I think I know what's going on with this: it doesn't have the ability=loyalty, so it's not able to work properly as a planeswalker. I don't think I'm capable of doing this one, after all - my bad for bringing this up, I should've realized it was a tough card, just forget it.
Edit: I think I know what's going on with this: it doesn't have the ability=loyalty, so it's not able to work properly as a planeswalker. I don't think I'm capable of doing this one, after all - my bad for bringing this up, I should've realized it was a tough card, just forget it.
- PalladiaMors
- Posts: 343
- Joined: 12 Jul 2014, 17:40
- Has thanked: 36 times
- Been thanked: 22 times
Re: Card Contributions
by melvin » 19 Mar 2015, 05:51
It looks like you are missing the hidden property on the transformed face, see https://github.com/magarena/magarena/bl ... _Fiend.txt for an example. We should have this in the game, please email what you've got so far to magarena@googlegroups.comPalladiaMors wrote:Now it transforms, but none of Veil-Cursed's abilities can be activated.
Fixes integrated, do take note of MagicWhenSelfLeavesPlayTrigger. Updated in https://github.com/magarena/magarena/co ... cd70da9625PalladiaMors wrote:Oh and please notice the edit about the fixes above, those 3 cards are currently completely broken.
-
melvin - AI Programmer
- Posts: 1062
- Joined: 21 Mar 2010, 12:26
- Location: Singapore
- Has thanked: 36 times
- Been thanked: 459 times
Re: Card Contributions
by muppet » 19 Mar 2015, 12:05
Ok I'll keep a look out for cards marked main that should be something else. Does it also stop the ai using any abilities outside of main too e.g. Sakura Tribal Elder is marked main but you might quite often want to sacrifice it at other times?
Re: Card Contributions
by PalladiaMors » 19 Mar 2015, 13:02
It does works after adding the "hidden" word, so I'm trying to submit through Firemind.melvin wrote:We should have this in the game, please email what you've got so far to magarena@googlegroups.com
@muppet, permanents with activated abilities can have various different timing hints, one to guide the AI to cast the card, and others to guide it when activating its abilities. For instance, see Scavenging Ooze. The script file has timing=main, which is standard for creatures. That hint is related to when the card should be cast. If you have a look at the groovy file, where its ability is coded, you'll see on the third line "new MagicActivationHints(MagicTiming.Pump)". That hint guides it about when to activate this ability.
Sakura-Tribe Elder is done completely without groovy, so its ability is hard coded in the main code. If you can locate this ability in there, it should have a specific timing hint as well.
By the way, I didn't manage to get through that change to Snapcaster Mage's timing hint, it would probably be a good idea if you could post it as a bug report in the 1.59 bugs topic. That's a very played card and that timing hint could be improved.
- PalladiaMors
- Posts: 343
- Joined: 12 Jul 2014, 17:40
- Has thanked: 36 times
- Been thanked: 22 times
Who is online
Users browsing this forum: No registered users and 28 guests