Programming a card
Post MTG Forge Related Programming Questions Here
Moderators: timmermac, Blacksmith, KrazyTheFox, Agetian, friarsol, CCGHQ Admins
Re: Programming a card
by DennisBergkamp » 12 Dec 2009, 01:21
I don't think there's an easy way to get the actual active player though
-
DennisBergkamp - AI Programmer
- Posts: 2602
- Joined: 09 Sep 2008, 15:46
- Has thanked: 0 time
- Been thanked: 0 time
Re: Programming a card
by Triadasoul » 12 Dec 2009, 09:44
exactly. But it doesn't work at all, so i tried to experiment with it a little to know what i made wrong and I've found funny things that something wrong with the card name "Prowess of the Fair" and i supposed that it should be added somewhere else.DennisBergkamp wrote:Hmm, but shouldn't Prowess of the Fair be called through something like this:
- Code: Select all
else if (c.getName().equals("Prowess of the Fair") && destroyed.getType().contains("Elf")) && !destroyed.isToken() && !c.equals(destroyed) )
destroyCreature_Prowess_of_the_Fair(c, destroyed);
Here's the full code of mine:
- Code: Select all
else if (c.getName().equals("Prowess of the Fair") && destroyed.getType().contains("Elf") && !destroyed.isToken() && !c.equals(destroyed) )
destroyCreature_Prowess_of_the_Fair(c, destroyed);
private static void destroyCreature_Prowess_of_the_Fair(Card c, Card destroyed)
{
final Card crd = c;
final Card crd2 = c;
Ability ability = new Ability(c, "0")
{
public void resolve()
{
String player = crd.getController();
if (player.equals(Constant.Player.Human)) {
if (showDialog(crd2))
makeToken();
}
else
makeToken();
}
public void makeToken()
{
String player = crd.getController();
Card c = new Card();
c.setName("Elf Warrior");
c.setImageName("G 1 1 Elf Warrior");
c.setOwner(player);
c.setController(player);
c.setManaCost("G");
c.setToken(true);
c.addType("Creature");
c.addType("Elf");
c.addType("Warrior");
c.setBaseAttack(1);
c.setBaseDefense(1);
PlayerZone play = AllZone.getZone(Constant.Zone.Play, player);
play.add(c);
}
};
ability.setStackDescription("Prowess of the Fair - " + c.getController() +" may put a 1/1 green Elf Warrior creature token onto the battlefield.");
AllZone.Stack.add(ability);
}
- Triadasoul
- Posts: 223
- Joined: 21 Jun 2008, 20:17
- Has thanked: 0 time
- Been thanked: 4 times
Re: Programming a card
by DennisBergkamp » 14 Dec 2009, 19:58
Looking at the code, that should work... but I guess it doesn't, no idea why not though
-
DennisBergkamp - AI Programmer
- Posts: 2602
- Joined: 09 Sep 2008, 15:46
- Has thanked: 0 time
- Been thanked: 0 time
Re: Programming a card
by nantuko84 » 18 Dec 2009, 06:09
Triadasoul> don't you have debug?
as I use Forge architecture, I can say that I had similar problems when card names weren't trimmed.
To get to know this, try the code:
anyway let me know about the results (first I thought about logging, but as far as I remember there is no one in Forge)
as I use Forge architecture, I can say that I had similar problems when card names weren't trimmed.
To get to know this, try the code:
- Code: Select all
else if (c.getName().trim().equals("Prowess of the Fair") && destroyed.getType().contains("Elf")) && !destroyed.isToken() && !c.equals(destroyed) )
destroyCreature_Prowess_of_the_Fair(c, destroyed);
anyway let me know about the results (first I thought about logging, but as far as I remember there is no one in Forge)
Re: Programming a card
by Triadasoul » 18 Dec 2009, 08:24
I didn't try debug yet, cause for now i don't know how to use it for such a big program like this.
I tried your variant, it also doesn't work. Anyway thank your for your feedback.
I tried your variant, it also doesn't work. Anyway thank your for your feedback.
- Triadasoul
- Posts: 223
- Joined: 21 Jun 2008, 20:17
- Has thanked: 0 time
- Been thanked: 4 times
Re: Programming a card
by nantuko84 » 18 Dec 2009, 11:33
Triadasoul> I debuged it for you
there are two major issues:
1. filter for DestroyCardEffects, now it is
2. filter parses keywords and your card description doesn't contain any
so you need to add it or it's better to parse text as well
what I mean is:
2a.
not good as for me
2b update filter to parse text as well (and better with regexp)
p.s. btw, is there any way to put cards onto battlefield and into your hand before game starts?
now while testing Prowess of the Fair, I had to create deck with Llanowar Elves, Terrors, Forests, Swamps and Prowess of the Fair, but I had to be lucky to get them at once every game
how do you test your cards usually? is there any topic at forum regarding this?
there are two major issues:
1. filter for DestroyCardEffects, now it is
- Code: Select all
if (kw.startsWith("Whenever ") && kw.contains(" put into a graveyard from the battlefield,"))
return true;
2. filter parses keywords and your card description doesn't contain any
so you need to add it or it's better to parse text as well
what I mean is:
2a.
- Code: Select all
Prowess of the Fair
1 B
Tribal Enchantment Elf
Whenever another nontoken Elf is put into your graveyard from the battlefield, you may put a 1/1 green Elf Warrior creature token onto the battlefield.
Whenever another nontoken Elf is put into your graveyard from the battlefield, you may put a 1/1 green Elf Warrior creature token onto the battlefield.
not good as for me
2b update filter to parse text as well (and better with regexp)
- Code: Select all
public boolean addCard(Card c) {
ArrayList<String> keywords = c.getKeyword();
Pattern pattern = Pattern.compile(".*put into (\\S*) graveyard from the battlefield.*");
Matcher m;
for (String kw : keywords) {
m = pattern.matcher(kw);
if (kw.startsWith("Whenever") && m.matches())
return true;
}
m = pattern.matcher(c.getText());
return m.matches();
}
- Code: Select all
else if (c.getName().equals("Prowess of the Fair") && destroyed.getType().contains("Elf") && !destroyed.isToken() && !c.equals(destroyed))
destroyCreature_Soulcatcher(c, destroyed);
p.s. btw, is there any way to put cards onto battlefield and into your hand before game starts?
now while testing Prowess of the Fair, I had to create deck with Llanowar Elves, Terrors, Forests, Swamps and Prowess of the Fair, but I had to be lucky to get them at once every game
how do you test your cards usually? is there any topic at forum regarding this?
Re: Programming a card
by Marek14 » 18 Dec 2009, 13:23
Incantus has a special card that costs 0 and has a bunch of powerful abilities that allow you, basically, to do anything for free - generate mana, deal damage, destroy permanents, move cards from graveyard or exile back to hand, tutor, etc. It's exactly for the purpose of testing cards (I have made use of it many, many times). MTGO has something similar, called, I believe "Library of Congress".
Re: Programming a card
by nantuko84 » 18 Dec 2009, 14:52
I also have such card in MagicWars:
http://img686.imageshack.us/img686/3112 ... tefull.jpg
(though add lots of mana is not correct wording )
but such card takes time anyway, that's why I can set game state using plain text:
Llanowar Elves <-- Gives to your hand
2
top:Path to Exile <-- Puts on top
1
grave:Call of the Herd <-- Puts into graveyard
1
and battlefield on another file with the same format
and I know how it is usefull, that's why I'm asking and will be suprised if there is no such
http://img686.imageshack.us/img686/3112 ... tefull.jpg
(though add lots of mana is not correct wording )
but such card takes time anyway, that's why I can set game state using plain text:
Llanowar Elves <-- Gives to your hand
2
top:Path to Exile <-- Puts on top
1
grave:Call of the Herd <-- Puts into graveyard
1
and battlefield on another file with the same format
and I know how it is usefull, that's why I'm asking and will be suprised if there is no such
Re: Programming a card
by Triadasoul » 18 Dec 2009, 15:20
Thank you!! I should learn how to use the debugger in this context. 10 years passed since i used it last time in Pascal ))). As I thought it was somewhere else. Thank you for your code I'll add it today.
Usually I build a deck that completely consists of cards that I'm going to test (+lands of course, and accompanying cards, such as creatures for equipment) and playing with it against the same deck (to see how AI use it) and against some random decks. To speed things up you can change manacost in cards.txt to 1.
I haven't come on such a thread. I think the main thread about it is "Current Known Bug List"
UPD: I couldn't add the code cause i don't know what is "Pattern" and "Matcher" i'm a completely noob in java, but i'll change the condition to trigger Prowess of the Fair and such.
Usually I build a deck that completely consists of cards that I'm going to test (+lands of course, and accompanying cards, such as creatures for equipment) and playing with it against the same deck (to see how AI use it) and against some random decks. To speed things up you can change manacost in cards.txt to 1.
I haven't come on such a thread. I think the main thread about it is "Current Known Bug List"
UPD: I couldn't add the code cause i don't know what is "Pattern" and "Matcher" i'm a completely noob in java, but i'll change the condition to trigger Prowess of the Fair and such.
- Triadasoul
- Posts: 223
- Joined: 21 Jun 2008, 20:17
- Has thanked: 0 time
- Been thanked: 4 times
Re: Programming a card
by silly freak » 18 Dec 2009, 16:38
Pattern and Matcher are classes for regular expressions, for example, the pattern "a*" or "a+" would match the string "aaaa"
you can do cool things: "." is the wildcard (any character):
you can do cool things: "." is the wildcard (any character):
- Code: Select all
"Whenever .* put into a graveyard from the battlefield,"
___
where's the "trust me, that will work!" switch for the compiler?
Laterna Magica - blog, forum, project, 2010/09/06 release!
where's the "trust me, that will work!" switch for the compiler?
Laterna Magica - blog, forum, project, 2010/09/06 release!
- silly freak
- DEVELOPER
- Posts: 598
- Joined: 26 Mar 2009, 07:18
- Location: Vienna, Austria
- Has thanked: 93 times
- Been thanked: 25 times
Re: Programming a card
by Marek14 » 18 Dec 2009, 16:41
The thing is your card is still quite limited in what it can do. (For that matter, there is no need for it to be legendary - in Incantus I got great results by having each player have one in play to continue testing when one player had to pass turn to set up some new effects.)nantuko84 wrote:I also have such card in MagicWars:
http://img686.imageshack.us/img686/3112 ... tefull.jpg
(though add lots of mana is not correct wording )
but such card takes time anyway, that's why I can set game state using plain text:
Llanowar Elves <-- Gives to your hand
2
top:Path to Exile <-- Puts on top
1
grave:Call of the Herd <-- Puts into graveyard
1
and battlefield on another file with the same format
and I know how it is usefull, that's why I'm asking and will be suprised if there is no such
The Incantus version is, for one thing, playable from library (so you don't even have to draw it). Also, it has truly incredible number of abilities - perhaps the most powerful one is the ultimate mover that can move, I think, up to five cards from any zone to any other - that allows you to sculpt the game state any way you like. Adding counters, dealing damage, color changing and such are also basic abilities. Incantus might post the full code for it if he'd like to - I'm not sure if I can do that without permission.
Re: Programming a card
by Incantus » 18 Dec 2009, 18:21
Damn, i just wrote a long reply and it was lost (posting from my phone). In short, go ahead Marek14.
Re: Programming a card
by Marek14 » 18 Dec 2009, 19:32
- Code: Select all
name = 'Betatester Toolbox'
cardnum = 1
expansion = 'Testing'
type = characteristic('Artifact')
supertype = no_characteristic()
subtypes = no_characteristic()
cost = '0'
color = no_characteristic()
text = []
play_spell = play_permanent(cost)
in_play_role = Permanent(card, Artifact())
#################################
@activated(txt="0: Put into play from library", zone="library")
def effects(source):
payment = yield ManaCost("0")
yield NoTarget()
source.move_to(source.owner.play)
yield
abilities.add(effects)
@mana(txt="0: Add WUBRG")
def effects(source):
payment = yield ManaCost("0")
yield NoTarget()
add_mana(source.controller, "WUBRG")
yield
abilities.add(effects)
@activated(txt="0: Tap target permanent")
def effects(source):
payment = yield ManaCost("0")
target = yield Target(target_types=isPermanent)
target.tap()
yield
abilities.add(effects)
@activated(txt="0: Untap target permanent")
def effects(source):
payment = yield ManaCost("0")
target = yield Target(target_types=isPermanent)
target.untap()
yield
abilities.add(effects)
@activated(txt="0: Destroy target permanent")
def effects(source):
payment = yield ManaCost("0")
target = yield Target(target_types=isPermanent)
target.destroy()
yield
abilities.add(effects)
@activated(txt="0: Destroy all permanents")
def effects(source):
payment = yield ManaCost("0")
yield NoTarget()
for permanent in source.controller.play.get(isPermanent, all=True):
permanent.destroy()
yield
abilities.add(effects)
@activated(txt="0: Deal 1 damage to target player or creature")
def effects(source):
payment = yield ManaCost("0")
target = yield Target(target_types=isCreatureOrPlayer)
source.dealDamage(target, 1)
yield
abilities.add(effects)
@activated(txt="0: Put 2 1/1 green Elf creatures into play")
def effects(source):
payment = yield ManaCost("0")
target = yield NoTarget()
elf = {"type": "Creature","subtypes": ("Elf", "Warrior"),"color": "G", "power": 1, "toughness": 1}
source.controller.play_token(elf, 2)
yield
abilities.add(effects)
@activated(txt="0: Target creature gets +1/+1 until the end of the turn")
def effects(source):
payment = yield ManaCost("0")
target = yield Target(target_types=isCreature)
until_end_of_turn(augment_power_toughness(target, 1, 1))
yield
abilities.add(effects)
@activated(txt="0: Place a +1/+1 counter on target creature")
def effects(source):
payment = yield ManaCost("0")
target = yield Target(target_types=isCreature)
target.add_counters(PowerToughnessCounter(1, 1))
yield
abilities.add(effects)
@activated(txt="0: Place a -1/-1 counter on target creature")
def effects(source):
payment = yield ManaCost("0")
target = yield Target(target_types=isCreature)
target.add_counters(PowerToughnessCounter(-1, -1))
yield
abilities.add(effects)
@activated(txt="0: Target permanent is red until the end of the turn")
def effects(source):
payment = yield ManaCost("0")
target = yield Target(target_types=isPermanent)
until_end_of_turn(target.color.set('R'))
yield
abilities.add(effects)
@activated(txt="0: Steal control of target permanent until end of turn")
def effects(source):
payment = yield ManaCost("0")
target = yield Target(target_types=isPermanent)
until_end_of_turn(change_controller(target, source.controller))
yield
abilities.add(effects)
@activated(txt="0: Return target permanent card in a graveyard to play under your control")
def effects(source):
payment = yield ManaCost("0")
target = yield Target(target_types=isPermanentType, zone="graveyard")
target.move_to(source.controller.play)
yield
abilities.add(effects)
@activated(txt="0: Return target Permanent card that was removed from the game to play under your control")
def effects(source):
payment = yield ManaCost("0")
target = yield Target(target_types=isPermanentType, zone="removed")
target.move_to(source.controller.play)
yield
abilities.add(effects)
@activated(txt="0: Momentary blink all permanents")
def effects(source):
payment = yield ManaCost("0")
yield NoTarget()
permanents = source.controller.play.get(isPermanent, all=True)
for permanent in permanents: permanent.move_to(permanent.owner.removed)
yield
for permanent in permanents: permanent.move_to(permanent.owner.play)
yield
abilities.add(effects)
@activated(txt="0: Draw a card")
def effects(source):
payment = yield ManaCost("0")
yield NoTarget()
source.controller.draw()
yield
abilities.add(effects)
@activated(txt="0: Return target creature to its owner's hand")
def effects(source):
payment = yield ManaCost("0")
target = yield Target(isCreature)
target.move_to(target.owner.hand)
yield
abilities.add(effects)
@static_tracking(txt="Creatures you control have haste")
def ability():
def condition(source, card):
return source.controller == card.controller and isCreature(card)
def effects(card):
yield card.abilities.add(haste())
return condition, effects
abilities.add(ability)
Re: Programming a card
by Incantus » 19 Dec 2009, 04:25
Wow Marek, you have an old version. Here's the current one I use:
- Code: Select all
name = 'Betatester Toolbox'
cardnum = 1
expansion = 'Testing'
types = characteristic('Artifact')
supertypes = no_characteristic()
subtypes = no_characteristic()
cost = '0'
color = no_characteristic()
text = []
#################################
@static_tracking(events=TypesModifiedEvent(), txt="Creatures you control get +1/+1 and have haste")
def ability():
def condition(source, card):
return source.controller == card.controller and isCreature(card)
def effects(source, card):
yield card.augment_power_toughness_static(1,1), card.abilities.add(haste())
return condition, effects
#abilities.add(ability)
@activated(txt="0: Put into play from library", zone="library")
def ability():
def effects(controller, source):
payment = yield ManaCost("0")
yield NoTarget()
source.move_to("play")
yield
return effects
abilities.add(ability)
@mana(txt="0: Add WUBRG")
def ability():
def effects(controller, source):
payment = yield ManaCost("0")
yield NoTarget()
controller.add_mana("WUBRG")
yield
return effects
abilities.add(ability)
@activated(txt="0: Tap target permanent")
def ability():
def effects(controller, source):
payment = yield ManaCost("0")
target = yield Target(isPermanent)
target.tap()
yield
return effects
abilities.add(ability)
@activated(txt="0: Untap target permanent")
def ability():
def effects(controller, source):
payment = yield ManaCost("0")
target = yield Target(isPermanent)
target.untap()
yield
return effects
abilities.add(ability)
@activated(txt="0: Destroy target permanent")
def ability():
def effects(controller, source):
payment = yield ManaCost("0")
target = yield Target(isPermanent)
target.destroy()
yield
return effects
abilities.add(ability)
@activated(txt="0: Remove target permanent from the game")
def ability():
def effects(controller, source):
payment = yield ManaCost("0")
target = yield Target(isPermanent)
target.move_to("removed")
yield
return effects
abilities.add(ability)
@activated(txt="0: Destroy all permanents")
def ability():
def effects(controller, source):
payment = yield ManaCost("0")
yield NoTarget()
for permanent in controller.play.get(isPermanent, all=True):
permanent.destroy()
yield
return effects
abilities.add(ability)
@activated(txt="0: Momentary blink up to 5 target permanents")
def ability():
def effects(controller, source):
payment = yield ManaCost("0")
targets = yield MultipleTargets(isPermanent, number=5, up_to=True)
removed = [permanent.move_to("removed") for permanent in targets]
yield
permanents = [rfg.move_to("play") for rfg in removed]
yield
return effects
abilities.add(ability)
@activated(txt="0: Deal 1 damage to target player or creature")
def ability():
def effects(controller, source):
payment = yield ManaCost("0")
target = yield Target(isCreatureOrPlayer)
source.deal_damage(target, 1)
yield
return effects
abilities.add(ability)
@activated(txt="0: Deal 10 damage to target player or creature")
def ability():
def effects(controller, source):
payment = yield ManaCost("0")
target = yield Target(isCreatureOrPlayer)
source.deal_damage(target, 10)
yield
return effects
abilities.add(ability)
@activated(txt="0: Put 3 2/1 green Elf creature into play")
def ability():
def effects(controller, source):
payment = yield ManaCost("0")
target = yield NoTarget()
elf = {"types": "Creature","subtypes": ("Elf", "Warrior"),"color": "G", "P/T": (2,1)}
controller.play_tokens(elf, 3)
yield
return effects
abilities.add(ability)
@activated(txt="0: Target creature gets +1/+1 until the end of the turn")
def ability():
def effects(controller, source):
payment = yield ManaCost("0")
target = yield Target(isCreature)
until_end_of_turn(target.augment_power_toughness(1, 1))
yield
return effects
abilities.add(ability)
@activated(txt="0: Place a flood counter on target land")
def ability():
def effects(controller, source):
payment = yield ManaCost("0")
target = yield Target(isLand)
target.add_counters(Counter("flood"))
yield
return effects
abilities.add(ability)
@activated(txt="0: Place a +1/+1 counter on target creature")
def ability():
def effects(controller, source):
payment = yield ManaCost("0")
target = yield Target(isCreature)
target.add_counters(PowerToughnessCounter(1, 1))
yield
return effects
abilities.add(ability)
@activated(txt="0: Place a -1/-1 counter on target creature")
def ability():
def effects(controller, source):
payment = yield ManaCost("0")
target = yield Target(isCreature)
target.add_counters(PowerToughnessCounter(-1, -1))
yield
return effects
abilities.add(ability)
@activated(txt="0: Target creature gains shroud until the end of the turn")
def ability():
def effects(controller, source):
payment = yield ManaCost("0")
target = yield Target(isCreature)
until_end_of_turn(target.abilities.add(shroud()))
yield
return effects
abilities.add(ability)
@activated(txt="0: Target permanent is a color of your choice until the end of the turn")
def ability():
def effects(controller, source):
payment = yield ManaCost("0")
target = yield Target(isPermanent)
color = controller.getSelection("WUBRG", 1, prompt="Select color to set")
until_end_of_turn(target.color.set(color))
yield
return effects
abilities.add(ability)
@activated(txt="0: Target permanent loses all abilities until the end of the turn")
def ability():
def effects(controller, source):
payment = yield ManaCost("0")
target = yield Target(isPermanent)
until_end_of_turn(target.abilities.remove_all())
yield
return effects
abilities.add(ability)
@activated(txt="0: Steal control of target permanent until end of turn")
def ability():
def effects(controller, source):
payment = yield ManaCost("0")
target = yield Target(isPermanent)
until_end_of_turn(target.set_controller(controller))
yield
return effects
abilities.add(ability)
@activated(txt="0: Return target permanent card in a graveyard to play under your control")
def ability():
def effects(controller, source):
payment = yield ManaCost("0")
target = yield Target(isPermanentCard, zone="graveyard")
target.move_to(controller.play)
yield
return effects
abilities.add(ability)
@activated(txt="0: Draw a card")
def ability():
def effects(controller, source):
payment = yield ManaCost("0")
yield NoTarget()
controller.draw()
yield
return effects
abilities.add(ability)
@activated(txt="0: Target player discards hand")
def ability():
def effects(controller, source):
payment = yield ManaCost("0")
target = yield Target(isPlayer)
target.force_discard(-1)
yield
return effects
abilities.add(ability)
@activated(txt="0: Search a chosen zone for up to 3 cards and move them to another zone")
def ability():
def effects(controller, source):
payment = yield ManaCost("0")
yield NoTarget()
zones = ["play", "hand", "library", "graveyard", "removed"]
from_zone = controller.make_selection(zones, prompt="Move from zone")
zones.remove(from_zone)
to_zone = controller.make_selection(zones, prompt="Move to zone")
for card in controller.choose_from_zone(number=3, cardtype=isCard, zone=from_zone, action="card to move to %s"%to_zone, required=False):
card.move_to(to_zone)
yield
return effects
abilities.add(ability)
@activated(txt="0: Search your library for a permanent card and put that card into play")
def ability():
def effects(controller, source):
payment = yield ManaCost("0")
yield NoTarget()
for card in controller.choose_from_zone(number=1, cardtype=isPermanentCard, zone="library", action="permanent card to put into play", required=False):
card.move_to(controller.play)
yield
return effects
abilities.add(ability)
Re: Programming a card
by nantuko84 » 19 Dec 2009, 04:55
have you generated the picture for your card?
(with Incantus expansion symbol )
(with Incantus expansion symbol )
Who is online
Users browsing this forum: No registered users and 94 guests