Card Contributions
by ubeefx
Moderators: ubeefx, beholder, melvin, ShawnieBoy, Lodici, CCGHQ Admins
Re: Card Contributions
by frank » 31 Mar 2014, 22:03
truth to be told, java and me, we stopped being friends some 11 years ago and it's not coming back that easily at least I have an faint understanding what the code does...
didn't know I could test them myself - that's great. will do. thanks
didn't know I could test them myself - that's great. will do. thanks
Re: Card Contributions
by ShawnieBoy » 31 Mar 2014, 22:53
No problem! - Glad to be able to help. I'm not really a Java person myself, but thankfully a lot of the coding has been done so that it reads really well.
If you're testing new scripts, launch the Magarena-debug.bat file, it will run through all the cards abilities before you get into the game (will take a little longer to launch), so you won't need to put the card into a deck, then try a duel before it (potentially) crashes. The crash log will give you some pointers on where errors might be.
OK, now for Mistblade Shinobi:
Here we encounter a 'May' choice - bouncing a creature isn't mandatory, unlike Throat Slitter. MagicEvent only allows one 'choice' entry, but we've actually got two choices here - one 'May' choice and one 'Target' choice (do you want to bounce something, and if so, what?).
For cards that require only one simple yes/no may choice, say Rhox
To allow Mistblade Shinobi's choices, it's May choice is it's Target choice (You may return target creature)
When we get to the executeEvent(), we only want to do anything if the choice was 'yes', this is easily found with
Adding this to what you've got, we have the finished product:
But for some bad news...
Skullsnatcher has multiple targets, something we can't quite do yet. Devour works as it's not targeted (You sacrifice x creatures). But I like your logic in trying to get it to work, even with multiple triggers. I tend to veer away from any 'up to' or 'any number of' cards.
It's a shame, but he can go and live in the 'incomplete' folder for the time being, so your work isn't in vain
If you're testing new scripts, launch the Magarena-debug.bat file, it will run through all the cards abilities before you get into the game (will take a little longer to launch), so you won't need to put the card into a deck, then try a duel before it (potentially) crashes. The crash log will give you some pointers on where errors might be.
OK, now for Mistblade Shinobi:
Here we encounter a 'May' choice - bouncing a creature isn't mandatory, unlike Throat Slitter. MagicEvent only allows one 'choice' entry, but we've actually got two choices here - one 'May' choice and one 'Target' choice (do you want to bounce something, and if so, what?).
For cards that require only one simple yes/no may choice, say Rhox
- Code: Select all
new MagicMayChoice()
To allow Mistblade Shinobi's choices, it's May choice is it's Target choice (You may return target creature)
- Code: Select all
new MagicMayChoice(
MagicTargetChoice.TARGET_CREATURE_YOUR_OPPONENT_CONTROLS
)
- Code: Select all
"PN may\$ return target creature defending player controls to its owner's hand."
When we get to the executeEvent(), we only want to do anything if the choice was 'yes', this is easily found with
- Code: Select all
if (event.isYes()){
}
Adding this to what you've got, we have the finished product:
- Code: Select all
name=Mistblade Shinobi
url=http://magiccards.info/query?q=!mistblade%20shinobi
image=http://mtgimage.com/card/mistblade%20shinobi.jpg
value=4.267
rarity=C
type=Creature
subtype=Human,Ninja
cost={2}{U}
pt=1/1
ability=ninjutsu {U}
timing=main
requires_groovy_code
- Code: Select all
[
new MagicWhenDamageIsDealtTrigger() {
@Override
public MagicEvent executeTrigger(final MagicGame game,final MagicPermanent permanent,final MagicDamage damage) {
return (damage.getSource() == permanent &&
damage.getTarget().isPlayer() &&
damage.isCombat()) ?
new MagicEvent(
permanent,
new MagicMayChoice(
MagicTargetChoice.TARGET_CREATURE_YOUR_OPPONENT_CONTROLS
),
MagicBounceTargetPicker.create(),
this,
"PN may\$ return target creature defending player controls to its owner's hand."
):
MagicEvent.NONE;
}
@Override
public void executeEvent(final MagicGame game, final MagicEvent event) {
if (event.isYes()) {
event.processTargetPermanent(game, {
final MagicPermanent creature ->
game.doAction(new MagicRemoveFromPlayAction(creature,MagicLocationType.OwnersHand));
});
}
}
}
]
But for some bad news...
Skullsnatcher has multiple targets, something we can't quite do yet. Devour works as it's not targeted (You sacrifice x creatures). But I like your logic in trying to get it to work, even with multiple triggers. I tend to veer away from any 'up to' or 'any number of' cards.
It's a shame, but he can go and live in the 'incomplete' folder for the time being, so your work isn't in vain
-
ShawnieBoy - Programmer
- Posts: 601
- Joined: 02 Apr 2012, 22:42
- Location: UK
- Has thanked: 80 times
- Been thanked: 50 times
Re: Card Contributions
by frank » 31 Mar 2014, 23:14
I was testing the card myself... missed the may choice and it crashed due to naming a variable permanent and calling it creature later... the crash log is quite informative: told me exactly what I was doing wrong. liked that.
okay, that was fun the time being, maybe more later
okay, that was fun the time being, maybe more later
Re: Card Contributions
by frank » 01 Apr 2014, 05:37
got one more, however incomplete/faulty.
I can play a few turns, than crash and burn...
edit: found the mistake. now it's working like a charm. and in near mint condition, too
edit2: I'd certainly like to try Shuriken next. Do we have some means to unattach equips?
Higure, the Still Wind
I can play a few turns, than crash and burn...
edit: found the mistake. now it's working like a charm. and in near mint condition, too
edit2: I'd certainly like to try Shuriken next. Do we have some means to unattach equips?
Higure, the Still Wind
- Code: Select all
name=Higure, the Still Wind
url=http://magiccards.info/query?q=!higure,%20the%20still%20wind
image=http://mtgimage.com/card/higure,%20the%20still%20wind.jpg
value=3.900
rarity=R
type=Creature
subtype=Human,Ninja
cost={3}{U}{U}
pt=3/1
ability=ninjutsu {2}{U}{U}
timing=main
requires_groovy_code
- Code: Select all
def NINJA_FILTER=new MagicPermanentFilterImpl() {
public boolean accept(final MagicGame game,final MagicPlayer player,final MagicPermanent target) {
return target.isCreature() && target.hasSubType(MagicSubType.Ninja);
}
};
def TARGET_NINJA = new MagicTargetChoice(
NINJA_FILTER,
"target ninja"
)
def NINJA_CARD_FROM_LIBRARY = new MagicCardFilterImpl() {
public boolean accept(final MagicGame game,final MagicPlayer player,final MagicCard target) {
return target.hasSubType(MagicSubType.Ninja);
}
public boolean acceptType(final MagicTargetType targetType) {
return targetType == MagicTargetType.Library;
}
};
def A_NINJA_CARD_FROM_LIBRARY = new MagicTargetChoice(
NINJA_CARD_FROM_LIBRARY,
"a ninja card"
)
[
new MagicPermanentActivation(
new MagicActivationHints(MagicTiming.Attack),
"Unblockable"
) {
@Override
public Iterable<MagicEvent> getCostEvent(final MagicPermanent source) {
return [
new MagicPayManaCostEvent(source,"{2}")
];
}
@Override
public MagicEvent getPermanentEvent(final MagicPermanent source,final MagicPayedCost payedCost) {
return new MagicEvent(
source,
TARGET_NINJA,
MagicUnblockableTargetPicker.create(),
this,
"Target Ninja\$ is unblockable this turn."
);
}
@Override
public void executeEvent(final MagicGame game, final MagicEvent event) {
event.processTargetPermanent(game, {
final MagicPermanent creature ->
game.doAction(new MagicGainAbilityAction(creature,MagicAbility.Unblockable));
});
}
},
new MagicWhenDamageIsDealtTrigger() {
@Override
public MagicEvent executeTrigger(final MagicGame game,final MagicPermanent permanent,final MagicDamage damage) {
return (damage.getSource() == permanent &&
damage.getTarget().isPlayer() &&
damage.isCombat()) ?
new MagicEvent(
permanent,
new MagicMayChoice(),
this,
"PN may search his or her library for a ninja card, reveals it, puts it into PN's Hand, and shuffles PN's library."
):
MagicEvent.NONE;
}
@Override
public void executeEvent(final MagicGame game, final MagicEvent event) {
if (event.isYes()) {
game.addEvent(new MagicSearchIntoHandEvent(
event,
A_NINJA_CARD_FROM_LIBRARY
));
}
}
}
]
Re: Card Contributions
by melvin » 01 Apr 2014, 07:53
The current method for unattaching a permanent is to attach it to MagicPermanent.NONE. Will look into creating a more intuitive unattach action for next release.frank wrote:I'd certainly like to try Shuriken next. Do we have some means to unattach equips?
Thank for the new cards, and ShawnieBoy for helping to add the earlier ones to the project.
The easiest way for us to integrate your submission is using firemind.ch. Recommended to create an account on firemind.ch (for us to attribute the card to you) and submitting the cards via http://www.firemind.ch/card_script_submissions/new when you get them working. Try using firemind.ch for Higure, the Still Wind.
-
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 frank » 02 Apr 2014, 11:51
I hate to ask, but could somebody please help me again?
I tried Benthicore. This is how far I got:
Exception from controller.runGame: Unable to find target
java.lang.RuntimeException: Unable to find target
at magic.model.event.MagicEvent.getTarget(MagicEvent.java:434)
at magic.model.event.MagicEvent.getLegalTarget(MagicEvent.java:505)
at magic.model.event.MagicEvent.processTargetPermanent(MagicEvent.java:544)
at Benthicore$3.executeEvent(Benthicore.groovy:42)
at magic.model.event.MagicEvent.executeEvent(MagicEvent.java:618)
at magic.model.MagicGame.executeEvent(MagicGame.java:752)
at magic.model.stack.MagicItemOnStack.resolve(MagicItemOnStack.java:120)
at magic.model.action.MagicStackResolveAction.doAction(MagicStackResolveAction.java:13)
at magic.model.MagicGame.doAction(MagicGame.java:532)
at magic.model.phase.MagicPhase.executePhase(MagicPhase.java:43)
at magic.model.MagicGame.executePhase(MagicGame.java:431)
at magic.ai.MCTSAI.getNextChoices(MCTSAI.java:426)
at magic.ai.MCTSAI.randomPlay(MCTSAI.java:397)
at magic.ai.MCTSAI.access$000(MCTSAI.java:66)
at magic.ai.MCTSAI$1.run(MCTSAI.java:186)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
at java.util.concurrent.FutureTask.run(FutureTask.java:262)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:744)
What I'm missing here?
I tried Benthicore. This is how far I got:
- Code: Select all
name=Benthicore
url=http://magiccards.info/query?q=%21benthicore
image=http://mtgimage.com/card/benthicore.jpg
value=3.095
rarity=U
type=Creature
subtype=Elemental
cost={6}{U}
pt=5/5
timing=main
requires_groovy_code
- Code: Select all
def UNTAPPED_MERFOLK_YOU_CONTROL=new MagicPermanentFilterImpl(){
public boolean accept(final MagicGame game,final MagicPlayer player,final MagicPermanent target)
{
return target.isCreature() && target.hasSubType(MagicSubType.Merfolk) && !target.isTapped() && !target.isOpponent(player);
}
};
def AN_UNTAPPED_MERFOLK_YOU_CONTROL = new MagicTargetChoice(UNTAPPED_MERFOLK_YOU_CONTROL,"an untapped merfolk creature you control");
[
new MagicWhenComesIntoPlayTrigger()
{
@Override
public MagicEvent executeTrigger(final MagicGame game,final MagicPermanent permanent, final MagicPayedCost payedCost)
{
return new MagicEvent(permanent,this,"PN puts two 1/1 blue Merfolk Wizard creature token onto the battlefield.");
}
@Override
public void executeEvent(final MagicGame game, final MagicEvent event)
{
game.doAction(new MagicPlayTokenAction(event.getPlayer(),TokenCardDefinitions.get("1/1 blue Merfolk Wizard creature token")));
game.doAction(new MagicPlayTokenAction(event.getPlayer(),TokenCardDefinitions.get("1/1 blue Merfolk Wizard creature token")));
}
},
new MagicPermanentActivation(new MagicActivationHints(MagicTiming.Removal),"Untap")
{
@Override
public Iterable<MagicEvent> getCostEvent(final MagicPermanent source)
{
return [new MagicTapPermanentEvent(source, AN_UNTAPPED_MERFOLK_YOU_CONTROL),new MagicTapPermanentEvent(source, AN_UNTAPPED_MERFOLK_YOU_CONTROL)];
}
@Override
public MagicEvent getPermanentEvent(final MagicPermanent source, final MagicPayedCost payedCost)
{
return new MagicEvent(source,this,"Untap SN. SN gains shroud until end of turn.");
}
@Override
public void executeEvent(final MagicGame game, final MagicEvent event) {
event.processTargetPermanent(game, {
final MagicPermanent creature ->
game.doAction(new MagicUntapAction(creature));
game.doAction(new MagicGainAbilityAction(creature,MagicAbility.Shroud));
});
}
}
]
Exception from controller.runGame: Unable to find target
java.lang.RuntimeException: Unable to find target
at magic.model.event.MagicEvent.getTarget(MagicEvent.java:434)
at magic.model.event.MagicEvent.getLegalTarget(MagicEvent.java:505)
at magic.model.event.MagicEvent.processTargetPermanent(MagicEvent.java:544)
at Benthicore$3.executeEvent(Benthicore.groovy:42)
at magic.model.event.MagicEvent.executeEvent(MagicEvent.java:618)
at magic.model.MagicGame.executeEvent(MagicGame.java:752)
at magic.model.stack.MagicItemOnStack.resolve(MagicItemOnStack.java:120)
at magic.model.action.MagicStackResolveAction.doAction(MagicStackResolveAction.java:13)
at magic.model.MagicGame.doAction(MagicGame.java:532)
at magic.model.phase.MagicPhase.executePhase(MagicPhase.java:43)
at magic.model.MagicGame.executePhase(MagicGame.java:431)
at magic.ai.MCTSAI.getNextChoices(MCTSAI.java:426)
at magic.ai.MCTSAI.randomPlay(MCTSAI.java:397)
at magic.ai.MCTSAI.access$000(MCTSAI.java:66)
at magic.ai.MCTSAI$1.run(MCTSAI.java:186)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
at java.util.concurrent.FutureTask.run(FutureTask.java:262)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:744)
What I'm missing here?
Re: Card Contributions
by melvin » 02 Apr 2014, 14:29
1) The second ability's executeEvent shouldn't be using processTargetPermanet as there is no target. The Untap and Gain action should be applied to event.getPermanent(). See executeEvent of Ghost_Hounds.groovy as an example.
2) A more subtle problem is that the second ability needs an activation condition so that it can only be activated when the player has at least two untapped merfolks. The game is not smart enough to deduce this condition, it will allow the ability to be activated when there is one untapped merfolk, but later it would get stuck paying the cost. See Eater_of_Hope.groovy for an example.
2) A more subtle problem is that the second ability needs an activation condition so that it can only be activated when the player has at least two untapped merfolks. The game is not smart enough to deduce this condition, it will allow the ability to be activated when there is one untapped merfolk, but later it would get stuck paying the cost. See Eater_of_Hope.groovy for an example.
-
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 frank » 02 Apr 2014, 14:49
Meanwhile I was working on Bringer of the Black Dawn. Good news: that one works, but still I ran into something I need to know:
I just posted it on firemind nevertheless... will look into your suggestions now. Thanks for spoon-feeding me.
edit: that did the trick, thanks again - posted to firemind.
- Code: Select all
def CARD_FROM_LIBRARY = new MagicCardFilterImpl() {
public boolean accept(final MagicGame game,final MagicPlayer player,final MagicCard target) {
return true;
}
public boolean acceptType(final MagicTargetType targetType) {
return targetType == MagicTargetType.Library;
}
};
def A_CARD_FROM_LIBRARY = new MagicTargetChoice(
CARD_FROM_LIBRARY,
"a card"
);
[
new MagicAtUpkeepTrigger() {
@Override
public MagicEvent executeTrigger(final MagicGame game,final MagicPermanent permanent,final MagicPlayer upkeepPlayer) {
return (permanent.isController(upkeepPlayer)) ?
new MagicEvent(
permanent,
new MagicMayChoice(),
this,
"PN may\$ pay 2 Life to search his or her library for a card, then shuffle his or her library and put that card on top of it."
):
MagicEvent.NONE;
}
@Override
public void executeEvent(final MagicGame game, final MagicEvent event) {
if (event.isYes()){
game.addEvent(new MagicPayLifeEvent(event.getPermanent(), 2));
game.addEvent(new MagicSearchOntoLibraryEvent(event,A_CARD_FROM_LIBRARY));
}
}
}
]
I just posted it on firemind nevertheless... will look into your suggestions now. Thanks for spoon-feeding me.
edit: that did the trick, thanks again - posted to firemind.
Re: Card Contributions
by ShawnieBoy » 02 Apr 2014, 17:56
The payment timing should be fine - it's how the Ravnica shock lands are coded as well. There's no real timing gap between paying and searching. It's worded that way so it prevents you from paying multiple amounts of life.
Thanks for the submissions! Keep them coming - Although do remember to log in on firemind.ch, they're being submitted as Guest
Thanks for the submissions! Keep them coming - Although do remember to log in on firemind.ch, they're being submitted as Guest
-
ShawnieBoy - Programmer
- Posts: 601
- Joined: 02 Apr 2012, 22:42
- Location: UK
- Has thanked: 80 times
- Been thanked: 50 times
Re: Card Contributions
by frank » 02 Apr 2014, 18:02
right, wasn't logged in. I see it now. Bringer of the Red Dawn was mine, too...
There's is but one thing, that keeps me wondering: as by the rules, you can't pay 2 life, if you don't have 2 life. The way I did it you are asked the May-Option and the paylife action occurs later, what happens if you have exactly 1 life left?
edit: I give up on Shuriken - for now.
proved to difficult for me, sorry.
There's is but one thing, that keeps me wondering: as by the rules, you can't pay 2 life, if you don't have 2 life. The way I did it you are asked the May-Option and the paylife action occurs later, what happens if you have exactly 1 life left?
edit: I give up on Shuriken - for now.
proved to difficult for me, sorry.
Re: Card Contributions
by frank » 03 Apr 2014, 21:07
I'm terribly sorry. I submitted two cards which weren't working properly. Didn'T get the color as they should. As soon as I discovered it, I fixed it and tried to re-submit them, but firemind wouldn't let me. So here the correct code:
Genju of the Cedars:
Genju of the Cedars:
- Code: Select all
name=Genju of the Cedars
url=http://magiccards.info/query?q=%21genju%20of%20the%20cedars
image=http://mtgimage.com/card/genju%20of%20the%20cedars.jpg
value=4.115
rarity=U
type=Enchantment
subtype=Aura
cost={G}
enchant=pump,pos forest
timing=enchantment
requires_groovy_code
- 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(4,4);
}
};
def ST = new MagicStatic(MagicLayer.Type, MagicStatic.UntilEOT) {
@Override
public int getTypeFlags(final MagicPermanent permanent,final int flags) {
return flags | MagicType.Creature.getMask();
}
@Override
public void modTypeFlags(final MagicPermanent permanent, final Set<MagicType> flags) {
flags.add(MagicType.Creature);
}
@Override
public void modSubTypeFlags(final MagicPermanent permanent, final Set<MagicSubType> flags) {
flags.add(MagicSubType.Spirit);
}
};
def LC = new MagicStatic(MagicLayer.Color, MagicStatic.UntilEOT) {
@Override
public int getColorFlags(final MagicPermanent permanent,final int flags) {
return MagicColor.Green.getMask();
}
};
[
new MagicPermanentActivation(
[
new MagicArtificialCondition(
MagicConditionFactory.ManaCost("{3}")
)
],
new MagicActivationHints(MagicTiming.Animate),
"Animate"
) {
@Override
public Iterable<MagicEvent> getCostEvent(final MagicPermanent source) {
return [new MagicPayManaCostEvent(source,"{2}")];
}
@Override
public MagicEvent getPermanentEvent(final MagicPermanent source,final MagicPayedCost payedCost) {
return new MagicEvent(
source.getEnchantedPermanent(),
this,
"SN becomes a 4/4 green Spirit creature until end of turn." +
"It's still a land."
);
}
@Override
public void executeEvent(final MagicGame game, final MagicEvent event) {
game.doAction(new MagicBecomesCreatureAction(event.getPermanent(),PT,ST,LC));
}
},
new MagicWhenOtherDiesTrigger() {
@Override
public MagicEvent executeTrigger(
final MagicGame game,
final MagicPermanent permanent,
final MagicPermanent died) {
return (permanent.getEnchantedPermanent() == died) ?
new MagicEvent(
permanent,
permanent.getCard(),
this,
"Return RN to its owner's hand."
):
MagicEvent.NONE;
}
@Override
public void executeEvent(final MagicGame game, final MagicEvent event) {
final MagicCard card = event.getRefCard();
if (card.isInGraveyard()) {
game.doAction(new MagicRemoveCardAction(card,MagicLocationType.Graveyard));
game.doAction(new MagicMoveCardAction(card,MagicLocationType.Graveyard,MagicLocationType.OwnersHand));
}
}
}
]
- Code: Select all
name=Genju of the Falls
url=http://magiccards.info/query?q=%21genju%20of%20the%20falls
image=http://mtgimage.com/card/genju%20of%20the%20falls.jpg
value=4.221
rarity=U
type=Enchantment
subtype=Aura
cost={U}
enchant=pump,pos island
timing=enchantment
requires_groovy_code
- 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(3,2);
}
};
def AB = new MagicStatic(MagicLayer.Ability, MagicStatic.UntilEOT) {
@Override
public void modAbilityFlags(final MagicPermanent source,final MagicPermanent permanent,final Set<MagicAbility> flags) {
permanent.addAbility(MagicAbility.Flying, flags);
}
};
def ST = new MagicStatic(MagicLayer.Type, MagicStatic.UntilEOT) {
@Override
public int getTypeFlags(final MagicPermanent permanent,final int flags) {
return flags | MagicType.Creature.getMask();
}
@Override
public void modTypeFlags(final MagicPermanent permanent, final Set<MagicType> flags) {
flags.add(MagicType.Creature);
}
@Override
public void modSubTypeFlags(final MagicPermanent permanent, final Set<MagicSubType> flags) {
flags.add(MagicSubType.Spirit);
}
};
def LC = new MagicStatic(MagicLayer.Color, MagicStatic.UntilEOT) {
@Override
public int getColorFlags(final MagicPermanent permanent,final int flags) {
return MagicColor.Blue.getMask();
}
};
[
new MagicPermanentActivation(
[
new MagicArtificialCondition(
MagicConditionFactory.ManaCost("{3}")
)
],
new MagicActivationHints(MagicTiming.Animate),
"Animate"
) {
@Override
public Iterable<MagicEvent> getCostEvent(final MagicPermanent source) {
return [new MagicPayManaCostEvent(source,"{2}")];
}
@Override
public MagicEvent getPermanentEvent(final MagicPermanent source,final MagicPayedCost payedCost) {
return new MagicEvent(
source.getEnchantedPermanent(),
this,
"SN becomes a 3/2 blue Spirit creature with flying until end of turn." +
"It's still a land."
);
}
@Override
public void executeEvent(final MagicGame game, final MagicEvent event) {
game.doAction(new MagicBecomesCreatureAction(event.getPermanent(),PT,AB,ST,LC));
}
},
new MagicWhenOtherDiesTrigger() {
@Override
public MagicEvent executeTrigger(
final MagicGame game,
final MagicPermanent permanent,
final MagicPermanent died) {
return (permanent.getEnchantedPermanent() == died) ?
new MagicEvent(
permanent,
permanent.getCard(),
this,
"Return RN to its owner's hand."
):
MagicEvent.NONE;
}
@Override
public void executeEvent(final MagicGame game, final MagicEvent event) {
final MagicCard card = event.getRefCard();
if (card.isInGraveyard()) {
game.doAction(new MagicRemoveCardAction(card,MagicLocationType.Graveyard));
game.doAction(new MagicMoveCardAction(card,MagicLocationType.Graveyard,MagicLocationType.OwnersHand));
}
}
}
]
Re: Card Contributions
by melvin » 04 Apr 2014, 01:39
No worries, it happens all the time. Perhaps we should make the card scripts more like a wiki page.
I've made the fixed you suggested plus some other ones (there isn't a modTypeFlags method) in https://code.google.com/p/magarena/sour ... 057aac81e8
I've made the fixed you suggested plus some other ones (there isn't a modTypeFlags method) in https://code.google.com/p/magarena/sour ... 057aac81e8
-
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 frank » 04 Apr 2014, 10:23
but there is a modSubTypeFlag method. I assumed it would work... but couldn't get MagicType.Legendary onto that land enchanted by Genju of the Realms, so used the code from Blinkmoth Nexus. Thanks for cleaning it up.
say, is there a way to find out if a creature did damage to a player this turn?
I was trying to implement Spear of Heliod yesterday, but didn't find anything useful in the class definitions.
say, is there a way to find out if a creature did damage to a player this turn?
I was trying to implement Spear of Heliod yesterday, but didn't find anything useful in the class definitions.
Re: Card Contributions
by ShawnieBoy » 04 Apr 2014, 20:58
There's a playerState flag WasDealtDamage, that is used by effects such as Bloodlust. But that's as close as it gets.
I'm not sure if it would later be possible to add variables to that, to show and list the sources of damage.
I'm not sure if it would later be possible to add variables to that, to show and list the sources of damage.
-
ShawnieBoy - Programmer
- Posts: 601
- Joined: 02 Apr 2012, 22:42
- Location: UK
- Has thanked: 80 times
- Been thanked: 50 times
Re: Card Contributions
by frank » 04 Apr 2014, 23:26
and the other way round? flag the creature boolean hasDealtDamageToPlayerThisTurn(MagicPlayer player){...}
Who is online
Users browsing this forum: No registered users and 4 guests