Re: Help implementing a card
Posted: 09 Apr 2016, 16:59
by MarcoMarin
Huge notes produced while mowing through the Antiquities set.
Take any one card question I ask below to help me out and feel free to ignore the rest. I'll be glad to clarify any poorly written passage here
Some may like to know there were 3 requested cards amongst them: Artifact Possession, Tawnos's Coffin and Shapeshifter. Let me know if there is a bug in Tawnos' Coffin, 'cause I'll have to fix Oubliette as well.
Take any one card question I ask below to help me out and feel free to ignore the rest. I'll be glad to clarify any poorly written passage here
Some may like to know there were 3 requested cards amongst them: Artifact Possession, Tawnos's Coffin and Shapeshifter. Let me know if there is a bug in Tawnos' Coffin, 'cause I'll have to fix Oubliette as well.
- | Open
- Artifact Possession (hey! my first 'requested' card completed ):
Non-fatal "bug": the effect: "DamageAttachedControllerEffect"'s static text says "creature's controller", although the code begs to differ so it won't cause any problems here.
Haunting Wind & Powerleech: the effect: DamageControllerEffect, will damage the source of the event (whatever triggered it) OR the controller of Haunting Winds itself?; Either that card or Powerleech (which is the opposite) will need further work depending on the answer.; Also, do weird game modes (e.g. 2 headed giant) assign anything other than "opponent" to any other player? There should probably be a constant for that (SourceController.OPPONENT), but I could not find any (except target, tho N/A).. no prob in this case, cause the event was conveniently available (not always the case I've found out other times =/)
Artifact Ward: is that any different from (today's) vanilla protection from artifact? Maybe the last part about "target of abilities" would have to be added?
btw, sometimes I have to create a duplicate ability inside the same set and Java complains. I'm renaming them with integers (2, 3, etc) to avoid breaking all cards if 1 is modified. Of course, the ideal would be to have a canonical ability to call from every one but.. until then, this seems the most future proof.
No Rest for the Wicked, its watcher says it only intercepts controller events, but I see nothing specific in the code. Is the Target there referring to this? It would seem like it refers to the card itself, the source which triggered the event. No? (also, the watcher scope is set to 'game' not 'player')
Urza's Miter: gotta test if sourceFirstTarget from the triggered Ability indeed corresponds to the sacrificed artifact. Otherwise the symptom will be it allowing you to gain life for sacrificed artifacts.
Jandor's Ring: Wow.. had to weave together a whole bunch of stuff for this one, not particularly complex any of them but numerous. Question: Should I create a new effect inside a oneShotEffect (much easier, I don't have the target card available at construction time), or should I extend the effect I want and set my own private variables to the values I need once they get available (inside apply)
Rocket Launcher (but also for above, Jandors Ring): should I used cleanup step Post, or At end of turn, or even end of turn post, or even beginning of the next turn? I know the card says "at the end", but in code I have to ensure there is no way to cast stuff in between because I'm resetting the counter that says a new turn begins so the watcher can keep track of the new turn without denying the last turn effect (if any). Im going with clean up post.
Goblin Artisans: The text seem to explicit exclude itself ("ANOTHER"), right? This would allow for untapping and "re-sacrificing" the same artifact. But it could also be a more loose meaning of "another". This was obviously meant to avoid the same player buying many cards for the price of 1(which I'm not even sure it does, it doesn't forbid the flip if you don't have an artifact tho it thought(ought?) it did? ), but back then there wasn't many (any?) cards that could say, rename cards (into artisan), redirect targets (so an opponent could target the player's artifact before he does) or even outright add abilities so it could any targets.
Also, I'm taking "counter" here to mean sacrifice. And I'm doing it directly, should I call the sacrifice target effect instead? (I already handled the playerId so maybe not necessary?)
A bit more technical: I did not see a overridable init which means it would be very inefficient to have a "targettedByName"(or Id, etc) Predicate, since it would have to go over and over again through each and every card in the battlefield for every one else(every input).. with init, it can save the results of the initial filter (since it's "byName" predicate), which arguably can never have more than 8 cards on the BF in the worst case (and usually only 1: the very source of this, I'd bet).
Noticed something strange in the code: SourceOnBattlefieldControlUnchangedCondition, shouldnt the permanent controller be compared somewhere? Unless the ability that triggers the condition doesn't change controller as the source does (which sounds strange to me)
Reverse Polarity: Doesn't seem like the game has this history capability, which is probably why everything changed to "the next event like this that happens (e.g. prevent damage)", even though it would be extremely useful.. I know I said that before for Jandor's Ring, since I didn't know about watchers yet. (Hey, bumped the ARN completion to 92.31%)
This time doesn't seem to have a work around (ok, I think I saw a way to access the log :p) But, this would lessen the need for watchers (actually it is like having built-in watchers, from the start of each duel, as a clue ) or at least reducing somewhat the complexity of coding cards. Is there a better way to do this? I think I better wait for this feature?
Clockwork Avian: gen-cards.pl complained about "Set not found in known sets: Beatdown Box set"
A question also for Helix Pinnacle (from where I copied this effect), should there be another "true" after "inform players", so the counters are putOnCard? (that's the name of the flag).
Armageddon Clock: Just wondering.. new Counter(CounterType.DOOM.getName(), 1) is equivalent to CounterType.DOOM.createInstance())? Or is the enum different from the string? (returned by getName)
Tetravus: While researching for this card, noticed another weird thing on another card: "Living Artifact", it seems to be marking false for the isOptional flag, which the card says "you may" so should be true?
I've seen other abilities which had a flag to enable/disable multiple uses (say, at the same turn), I don't see it on BeginningOfUpkeepTriggeredAbility, does this mean it is enable for default? (I think it should) Or will I have to code an ability to take RemovedCountersForCostValue instead? If someone could test tetravus please, that'd be great.
I've created a brand new Ability: CantBeEnchantedAbility, the IDE warns me the IF statement (when I check if it's being target by enchantment/aura) is redundant tho, I can't see why. This happens with either conditions alone.
BTW, that new ability may be useful for spjspj, who's marked he's coding Guardian Beast from ARN? It just need to bring the "keep auras already there" from the protection ability. Guardian Beast now only needs a way to avoid artifacts taking control.
Technically, the rule doesn't say if "Tetravite" is the card's name or subtype, probably both and if only 1 is true/important then I'd say it's the latter. There are cards that change subtype, are there cards that change name? Just wondering..
Still on Tetravus, the ability to take counters off and create tokens, asks for a condition (namely, having 1+ counter). I don't see the need to ask if the player controls a token, to reverse this process, since I already filter for that specific token, it just wouldn't find any. Does this cause problems, and if not, why ask in the former case for that matter? Not having counters wouldn't just deny the player the ability anyway? I'd assume it's being used in the "canPay" function?
Tawnos's Coffin: btw, Fixed Oubliette (returns tapped), please have the requester of Tawnos' Coffin test it, because any problems there I gotta fix Oubliette as well. I think I see a bug already, about returning to the owner instead of the controller. But I'm also worried about the default behavior of the built-in Exile/ReturnFromExile Effects, as it concerns Counters.
Shapeshifter: Some heavy shenanigans with global, I mean, 'public' variables there need testing.. Speaking of which, in the card Mindblaze, its "apply" function never returns true. :-/
gen-card.pl Script got verbose all of a sudden? it repeats every name of every card twice, and before outputting "cards generated" it repeats everything again...