Card Contributions
by ubeefx
Moderators: ubeefx, beholder, melvin, ShawnieBoy, Lodici, CCGHQ Admins
Re: Card Contributions
by ShawnieBoy » 14 Feb 2014, 06:00
I've been having some problems with Trap Digger (I knew I would, but not what I was expecting)
I've been getting a NullPointerException at MagicTargetChoice.getArtificialOptions
Oh, and I've already implemented MagicTargetChoice.NEG_TARGET_ATTACKING_CREATURE_WITHOUT_FLYING could it be that? I wouldn't have thought so.
I've been getting a NullPointerException at MagicTargetChoice.getArtificialOptions
- Code: Select all
CRASH REPORT FOR MAGARENA THREAD Thread[pool-6-thread-3,5,main]
CREATED ON 2014/02/14 05:48:49
MAGARENA VERSION 1.47, JRE 1.7.0_51, OS Windows 7_6.1 x86
================================
Used Memory: 100M
Free Memory: 47M
Total Memory: 148M
Max Memory: 247M
================================
Turn : 4 Phase : FirstMain Step : ActivePlayer Player : Computer Score : 202
0] Player : Player Life : 20 Delayed : Total=0
- Hand : Courier's Capsule
- Hand : Fieldmist Borderpost
- Hand : Fieldmist Borderpost
- Hand : Windreaver
- Hand : Windreaver
- Permanent : Academy Ruins Summoned
- Permanent : Gerrard's Battle Cry Summoned
- Permanent : Tundra Tapped
1] Player : Computer Life : 20 Delayed : Total=0
- Hand : Trap Digger
- Hand : Trap Digger
- Hand : Windreaver
- Hand : Island
- Hand : Gerrard's Battle Cry
- Hand : Academy Ruins
- Hand : Gerrard's Battle Cry
- Hand : Plains
- Permanent : Island
Stack : 0
1. MagicAddEventAction (EVENT: 0 Player may$ take a mulligan. ) = 0
2. MagicAddEventAction (EVENT: 1 Computer may$ take a mulligan. ) = 0
3. MagicExecuteFirstEventAction = 0
4. MagicExecuteFirstEventAction = 0
5. MagicAddEventAction (EVENT: 0 Play a card or ability.) = 0
6. MagicExecuteFirstEventAction = 0
7. MagicAddEventAction (EVENT: 1 Play a card or ability.) = 0
8. MagicExecuteFirstEventAction = 0
9. MagicAddEventAction (EVENT: 0 Play a card or ability.) = 0
10. MagicMarkerAction = 0
11. MagicLogMarkerAction = 0
12. MagicExecuteFirstEventAction = 0
13. MagicAddEventAction (EVENT: 0 Play Tundra. ) = 0
14. MagicExecuteFirstEventAction = 0
15. MagicRemoveCardAction (Tundra) = -631
16. MagicPlayCardAction (Tundra) = 936
17. MagicAddEventAction (EVENT: 0 Play a card or ability.) = 0
18. MagicExecuteFirstEventAction = 0
19. MagicAddEventAction (EVENT: 1 Play a card or ability.) = 0
20. MagicExecuteFirstEventAction = 0
21. MagicAddEventAction (EVENT: 0 Play a card or ability.) = 0
22. MagicExecuteFirstEventAction = 0
23. MagicAddEventAction (EVENT: 1 Play a card or ability.) = 0
24. MagicExecuteFirstEventAction = 0
25. MagicAddEventAction (EVENT: 0 Declare attackers.) = 0
26. MagicExecuteFirstEventAction = 0
27. MagicDeclareAttackersAction = 0
28. MagicAddEventAction (EVENT: 0 Play a card or ability.) = 0
29. MagicExecuteFirstEventAction = 0
30. MagicAddEventAction (EVENT: 1 Play a card or ability.) = 0
31. MagicExecuteFirstEventAction = 0
32. MagicAddEventAction (EVENT: 0 Play a card or ability.) = 0
33. MagicExecuteFirstEventAction = 0
34. MagicAddEventAction (EVENT: 1 Play a card or ability.) = 0
35. MagicExecuteFirstEventAction = 0
36. MagicAddEventAction (EVENT: 0 Play a card or ability.) = 0
37. MagicExecuteFirstEventAction = 0
38. MagicAddEventAction (EVENT: 1 Play a card or ability.) = 0
39. MagicExecuteFirstEventAction = 0
40. MagicReturnExiledAction = 0
41. MagicAddEventAction (EVENT: 0 Play a card or ability.) = 0
42. MagicExecuteFirstEventAction = 0
43. MagicAddEventAction (EVENT: 1 Play a card or ability.) = 0
44. MagicExecuteFirstEventAction = 0
45. MagicCleanupTurnTriggersAction = 0
46. MagicCleanupPlayerAction = 0
47. MagicCleanupPermanentAction = 0
48. MagicCleanupPlayerAction = 0
49. MagicCleanupTurnStaticsAction = 0
50. MagicAddEventAction (EVENT: 1 Play a card or ability.) = 0
51. MagicExecuteFirstEventAction = 0
52. MagicAddEventAction (EVENT: 0 Play a card or ability.) = 0
53. MagicExecuteFirstEventAction = 0
54. MagicDrawAction = -472
55. MagicAddEventAction (EVENT: 1 ...) = 0
56. MagicExecuteFirstEventAction = 0
57. MagicAddEventAction (EVENT: 1 Play a card or ability.) = 0
58. MagicExecuteFirstEventAction = 0
59. MagicAddEventAction (EVENT: 0 Play a card or ability.) = 0
60. MagicExecuteFirstEventAction = 0
61. MagicAddEventAction (EVENT: 1 Play a card or ability.) = 0
62. MagicExecuteFirstEventAction = 0
63. MagicAddEventAction (EVENT: 0 Play a card or ability.) = 0
64. MagicExecuteFirstEventAction = 0
65. MagicAddEventAction (EVENT: 1 Play a card or ability.) = 0
66. MagicExecuteFirstEventAction = 0
67. MagicAddEventAction (EVENT: 0 Play a card or ability.) = 0
68. MagicExecuteFirstEventAction = 0
69. MagicAddEventAction (EVENT: 1 Declare attackers.) = 0
70. MagicExecuteFirstEventAction = 0
71. MagicDeclareAttackersAction = 0
72. MagicAddEventAction (EVENT: 1 Play a card or ability.) = 0
73. MagicExecuteFirstEventAction = 0
74. MagicAddEventAction (EVENT: 0 Play a card or ability.) = 0
75. MagicExecuteFirstEventAction = 0
76. MagicAddEventAction (EVENT: 1 Play a card or ability.) = 0
77. MagicExecuteFirstEventAction = 0
78. MagicAddEventAction (EVENT: 0 Play a card or ability.) = 0
79. MagicExecuteFirstEventAction = 0
80. MagicAddEventAction (EVENT: 1 Play a card or ability.) = 0
81. MagicExecuteFirstEventAction = 0
82. MagicAddEventAction (EVENT: 1 Play Island. ) = 0
83. MagicExecuteFirstEventAction = 0
84. MagicRemoveCardAction (Island) = 380
85. MagicPlayCardAction (Island) = -684
86. MagicAddEventAction (EVENT: 1 Play a card or ability.) = 0
87. MagicExecuteFirstEventAction = 0
88. MagicAddEventAction (EVENT: 0 Play a card or ability.) = 0
89. MagicExecuteFirstEventAction = 0
90. MagicReturnExiledAction = 0
91. MagicAddEventAction (EVENT: 1 Play a card or ability.) = 0
92. MagicExecuteFirstEventAction = 0
93. MagicAddEventAction (EVENT: 0 Play a card or ability.) = 0
94. MagicExecuteFirstEventAction = 0
95. MagicCleanupTurnTriggersAction = 0
96. MagicCleanupPlayerAction = 0
97. MagicCleanupPermanentAction = 0
98. MagicCleanupPlayerAction = 0
99. MagicCleanupPermanentAction = 0
100. MagicCleanupTurnStaticsAction = 0
101. MagicChangeStateAction = 0
102. MagicChangeStateAction = 0
103. MagicAddEventAction (EVENT: 0 Play a card or ability.) = 0
104. MagicExecuteFirstEventAction = 0
105. MagicAddEventAction (EVENT: 1 Play a card or ability.) = 0
106. MagicExecuteFirstEventAction = 0
107. MagicDrawAction = 472
108. MagicAddEventAction (EVENT: 0 Play a card or ability.) = 0
109. MagicExecuteFirstEventAction = 0
110. MagicAddEventAction (EVENT: 1 Play a card or ability.) = 0
111. MagicExecuteFirstEventAction = 0
112. MagicAddEventAction (EVENT: 0 Play a card or ability.) = 0
113. MagicMarkerAction = 0
114. MagicLogMarkerAction = 0
115. MagicExecuteFirstEventAction = 0
116. MagicAddEventAction (EVENT: 0 Play Academy Ruins. ) = 0
117. MagicExecuteFirstEventAction = 0
118. MagicRemoveCardAction (Academy Ruins) = -223
119. MagicPlayCardAction (Academy Ruins) = 527
120. MagicAddEventAction (EVENT: 0 Play a card or ability.) = 0
121. MagicMarkerAction = 0
122. MagicLogMarkerAction = 0
123. MagicExecuteFirstEventAction = 0
124. MagicAddEventAction (EVENT: 0 Pay {W}$. Choose how to pay the mana cost.) = 0
125. MagicAddEventAction (EVENT: 0 Play Gerrard's Battle Cry. ) = 0
126. MagicTapAction (Tundra) = -5
127. MagicExecuteFirstEventAction = 0
128. MagicExecuteFirstEventAction = 0
129. MagicRemoveCardAction (Gerrard's Battle Cry) = -472
130. MagicPutItemOnStackAction (MagicCardOnStack,Gerrard's Battle Cry) = -1
131. MagicAddEventAction (EVENT: 0 ) = 0
132. MagicExecuteFirstEventAction = 0
133. MagicAddEventAction (EVENT: 0 Play a card or ability.) = 0
134. MagicExecuteFirstEventAction = 0
135. MagicAddEventAction (EVENT: 1 Play a card or ability.) = 0
136. MagicExecuteFirstEventAction = 0
137. MagicStackResolveAction = 0
138. MagicPlayCardFromStackAction (Gerrard's Battle Cry) = 776
139. MagicAddEventAction (EVENT: 0 Play a card or ability.) = 0
140. MagicExecuteFirstEventAction = 0
141. MagicAddEventAction (EVENT: 1 Play a card or ability.) = 0
142. MagicExecuteFirstEventAction = 0
143. MagicAddEventAction (EVENT: 0 Play a card or ability.) = 0
144. MagicExecuteFirstEventAction = 0
145. MagicAddEventAction (EVENT: 1 Play a card or ability.) = 0
146. MagicExecuteFirstEventAction = 0
147. MagicAddEventAction (EVENT: 0 Declare attackers.) = 0
148. MagicExecuteFirstEventAction = 0
149. MagicDeclareAttackersAction = 0
150. MagicAddEventAction (EVENT: 0 Play a card or ability.) = 0
151. MagicExecuteFirstEventAction = 0
152. MagicAddEventAction (EVENT: 1 Play a card or ability.) = 0
153. MagicExecuteFirstEventAction = 0
154. MagicAddEventAction (EVENT: 0 Play a card or ability.) = 0
155. MagicExecuteFirstEventAction = 0
156. MagicAddEventAction (EVENT: 1 Play a card or ability.) = 0
157. MagicExecuteFirstEventAction = 0
158. MagicAddEventAction (EVENT: 0 Play a card or ability.) = 0
159. MagicExecuteFirstEventAction = 0
160. MagicAddEventAction (EVENT: 1 Play a card or ability.) = 0
161. MagicExecuteFirstEventAction = 0
162. MagicReturnExiledAction = 0
163. MagicAddEventAction (EVENT: 0 Play a card or ability.) = 0
164. MagicExecuteFirstEventAction = 0
165. MagicAddEventAction (EVENT: 1 Play a card or ability.) = 0
166. MagicExecuteFirstEventAction = 0
167. MagicCleanupTurnTriggersAction = 0
168. MagicCleanupPlayerAction = 0
169. MagicCleanupPermanentAction = 0
170. MagicCleanupPermanentAction = 0
171. MagicCleanupPermanentAction = 0
172. MagicCleanupPlayerAction = 0
173. MagicCleanupPermanentAction = 0
174. MagicCleanupTurnStaticsAction = 0
175. MagicChangeStateAction = 0
176. MagicChangeStateAction = 0
177. MagicAddEventAction (EVENT: 1 Play a card or ability.) = 0
178. MagicExecuteFirstEventAction = 0
179. MagicAddEventAction (EVENT: 0 Play a card or ability.) = 0
180. MagicExecuteFirstEventAction = 0
181. MagicDrawAction = -400
182. MagicAddEventAction (EVENT: 1 ...) = 0
183. MagicExecuteFirstEventAction = 0
184. MagicAddEventAction (EVENT: 1 Play a card or ability.) = 0
185. MagicExecuteFirstEventAction = 0
186. MagicAddEventAction (EVENT: 0 Play a card or ability.) = 0
187. MagicExecuteFirstEventAction = 0
188. MagicAddEventAction (EVENT: 1 Play a card or ability.) = 0
Score = 203
Exception from controller.runGame: null
java.lang.NullPointerException
at magic.model.choice.MagicTargetChoice.getArtificialOptions(MagicTargetChoice.java:787)
at magic.model.choice.MagicChoice.getArtificialChoiceResults(MagicChoice.java:90)
at magic.model.event.MagicEvent.getArtificialChoiceResults(MagicEvent.java:370)
at magic.ai.MMAB$MMABWorker.runGame(MMAB.java:198)
at magic.ai.MMAB$MMABWorker.runGame(MMAB.java:226)
at magic.ai.MMAB$MMABWorker.runGame(MMAB.java:226)
at magic.ai.MMAB$MMABWorker.runGame(MMAB.java:179)
at magic.ai.MMAB$MMABWorker.runGame(MMAB.java:179)
at magic.ai.MMAB$MMABWorker.runGame(MMAB.java:179)
at magic.ai.MMAB$MMABWorker.runGame(MMAB.java:226)
at magic.ai.MMAB$MMABWorker.runGame(MMAB.java:226)
at magic.ai.MMAB$MMABWorker.runGame(MMAB.java:179)
at magic.ai.MMAB$MMABWorker.runGame(MMAB.java:226)
at magic.ai.MMAB$MMABWorker.runGame(MMAB.java:179)
at magic.ai.MMAB$MMABWorker.runGame(MMAB.java:179)
at magic.ai.MMAB$MMABWorker.runGame(MMAB.java:179)
at magic.ai.MMAB$MMABWorker.runGame(MMAB.java:226)
at magic.ai.MMAB$MMABWorker.runGame(MMAB.java:179)
at magic.ai.MMAB$MMABWorker.runGame(MMAB.java:226)
at magic.ai.MMAB$MMABWorker.runGame(MMAB.java:179)
at magic.ai.MMAB$MMABWorker.runGame(MMAB.java:179)
at magic.ai.MMAB$MMABWorker.runGame(MMAB.java:179)
at magic.ai.MMAB$MMABWorker.runGame(MMAB.java:179)
at magic.ai.MMAB$MMABWorker.evaluateGame(MMAB.java:251)
at magic.ai.MMAB$1.run(MMAB.java:94)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
- Code: Select all
name=Trap Digger
url=http://magiccards.info/sc/en/24.html
image=http://mtgimage.com/card/trap%20digger.jpg
value=1.242
rarity=R
type=Creature
subtype=Human,Soldier
cost={3}{W}
pt=1/3
ability=pay {2}{W},{T}:Put a trap counter on target land you control.
timing=main
requires_groovy_code
- Code: Select all
def TRAPPED_LAND_YOU_CONTROL=new MagicPermanentFilterImpl() {
public boolean accept(final MagicGame game,final MagicPlayer player,final MagicPermanent target) {
return target.isLand() && (target.getCounters(MagicCounterType.Trap)>=1) && target.isController(player);
}
};
def SACRIFICE_TRAPPED_LAND = new MagicTargetChoice(
TRAPPED_LAND_YOU_CONTROL,
MagicTargetHint.Negative,
"a land with a trap counter on it to sacrifice"
);
def TRAPPED_LAND_CONDITION =new MagicCondition() {
public boolean accept(final MagicSource source) {
return source.getController().getNrOfPermanents(TRAPPED_LAND_YOU_CONTROL)>=1;
}
};
[
new MagicPermanentActivation(
[TRAPPED_LAND_CONDITION],
new MagicActivationHints(MagicTiming.Removal),
"Damage"
) {
@Override
public Iterable<MagicEvent> getCostEvent(final MagicPermanent source) {
return [
new MagicSacrificePermanentEvent(source,SACRIFICE_TRAPPED_LAND)
];
}
@Override
public MagicEvent getPermanentEvent(final MagicPermanent source, final MagicPayedCost payedCost) {
return new MagicEvent(
source,
MagicTargetChoice.NEG_TARGET_ATTACKING_CREATURE_WITHOUT_FLYING,
new MagicDamageTargetPicker(3),
this,
"SN deals 3 damage to target attacking creature without flying\$."
);
}
@Override
public void executeEvent(final MagicGame game, final MagicEvent event) {
event.processTarget(game, {
final MagicTarget target ->
final MagicDamage damage=new MagicDamage(event.getSource(),target,3);
game.doAction(new MagicDealDamageAction(damage));
});
}
}
]
Oh, and I've already implemented MagicTargetChoice.NEG_TARGET_ATTACKING_CREATURE_WITHOUT_FLYING could it be that? I wouldn't have thought so.
-
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 » 20 Feb 2014, 12:25
The bug is triggered by "Put a trap counter on target land you control.", also occurred with Vedalken Infuser's "Put a charge counter on target artifact.".
The actual bug is MagicRuleEventAction.CounterOnChosen.getPicker returning null as the target picker in some cases. Fixed in https://code.google.com/p/magarena/sour ... 877835da73
The actual bug is MagicRuleEventAction.CounterOnChosen.getPicker returning null as the target picker in some cases. Fixed in https://code.google.com/p/magarena/sour ... 877835da73
-
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 » 23 Feb 2014, 04:20
Another head-scratcher for me again, this time with Darien, King of Kjeldor (and similar cards, yes there are some!)
Thanks for any help
- Code: Select all
name=Darien, King of Kjeldor
url=http://magiccards.info/cs/en/4.html
image=http://mtgimage.com/card/darien,%20king%20of%20kjeldor.jpg
value=4.294
rarity=R
type=Legendary,Creature
subtype=Human,Soldier
cost={4}{W}{W}
pt=3/3
timing=main
requires_groovy_code
- Code: Select all
[
new MagicWhenDamageIsDealtTrigger() {
@Override
public MagicEvent executeTrigger(final MagicGame game,final MagicPermanent permanent,final MagicDamage damage) {
final int amount = damage.getDealtAmount();
return (damage.getTarget() == permanent.getController()) ?
new MagicEvent(
permanent,
new MagicSimpleMayChoice(
MagicSimpleMayChoice.PLAY_TOKEN
amount,
MagicSimpleMayChoice.DEFAULT_YES
),
amount,
this,
"PN may\$ put RN 1/1 white Soldier creature tokens onto the battlefield."
):
MagicEvent.NONE;
}
@Override
public void executeEvent(final MagicGame game, final MagicEvent event) {
if (event.isYes()){
game.doAction(new MagicPlayTokenAction(
event.getPlayer(),
TokenCardDefinitions.get("1/1 white Soldier creature token"),
event.getRefInt()
));
}
}
}
]
Thanks for any help
-
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 » 23 Feb 2014, 05:37
There are two issues:ShawnieBoy wrote:Another head-scratcher for me again, this time with Darien, King of Kjeldor (and similar cards, yes there are some!)
1) missing comma after "MagicSimpleMayChoice.PLAY_TOKEN". The error message had me scratching my head for a while as well, it wasn't very helpful.
2) should be "new MagicPlayTokensAction" with an 's'
-
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 » 23 Feb 2014, 14:39
Doh! - Thanks for that, was too busy looking hard at a problem that wasn't there!melvin wrote:There are two issues:
1) missing comma after "MagicSimpleMayChoice.PLAY_TOKEN". The error message had me scratching my head for a while as well, it wasn't very helpful.
2) should be "new MagicPlayTokensAction" with an 's'
-
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 » 06 Mar 2014, 02:34
Ok, have another problem I can't fix - been in my head for a while now and I can't see why this isn't triggering. Tried all manner of variations on this and nothing seems to be working: Artificer's Hex
- Code: Select all
name=Artificer's Hex
url=http://www.magiccards.info/query?q=%21artificer%27s%20hex
image=http://mtgimage.com/card/artificer's%20hex.jpg
value=3.083
rarity=U
type=Enchantment
subtype=Aura
cost={B}
enchant=destroy,neg equipment
timing=aura
- Code: Select all
[
new MagicAtUpkeepTrigger() {
@Override
public MagicEvent executeTrigger(final MagicGame game,final MagicPermanent permanent,final MagicPlayer upkeepPlayer) {
return permanent.isController(upkeepPlayer) && permanent.getEnchantedPermanent().isValid() ?
new MagicEvent(
permanent,
this,
"Destroy "+permanent.getEnchantedPermanent().getEquippedCreature()+"."
):
MagicEvent.NONE;
}
@Override
public void executeEvent(final MagicGame game, final MagicEvent event) {
final MagicPermanent equippedCreature=event.getPermanent().getEnchantedPermanent().getEquippedCreature();
if (event.getPermanent().getEnchantedPermanent().isValid()) {
game.doAction(new MagicDestroyAction(equippedCreature));
}
}
}
]
-
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 » 06 Mar 2014, 06:08
Card script missing requires_groovy_code, this property is required to load the groovy code.
-
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 » 06 Mar 2014, 16:23
lol - why do I always miss the obvious? Thanks againmelvin wrote:Card script missing requires_groovy_code, this property is required to load the groovy code.
-
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 » 10 Mar 2014, 19:07
There's a couple of scripting values which I have to confess to not using, at first I thought they were left-over code from older versions and in a way, feel as though as they are either redundant or are able to be derived from other sources.
I've encountered the 'Static' value which appears on most 'lord' cards - isn't this information already defined in the lord ability? (leaving the static=all or static=player redundant?) It's not even referenced in the Wiki.
The removal value also seems very arbitrary. As a score from 1-5, it's currently seems to translate into a value equal to the damage/-X of the card. If this value is required, and unable to be obtained from elsewhere, then damage should rank far lower as a method of removal. Currently a card that does 5 damage to a creature has the same removal score as a card that can exile a permanent. Certainly not the same in power.
I'd see the ratings more like something like this: Taken as an average for the following scores.
Removal method
Target Type
Targets
From the example in the wiki, Vindicate should only rank about 3-4, as it can only destroy, and it's only one permanent. Lightning Bolt would only rank 3 as it can only remove one creature by dealing damage (Red damage at that, Ghostfire should rate higher). Vindicate can't really be compared to Planar Cleansing, Obliterate, Devastation or Plague Wind as a score of 5.
Although really, I'd love to see the abilities of the cards themselves used as a removal value of some kind.
I've encountered the 'Static' value which appears on most 'lord' cards - isn't this information already defined in the lord ability? (leaving the static=all or static=player redundant?) It's not even referenced in the Wiki.
The removal value also seems very arbitrary. As a score from 1-5, it's currently seems to translate into a value equal to the damage/-X of the card. If this value is required, and unable to be obtained from elsewhere, then damage should rank far lower as a method of removal. Currently a card that does 5 damage to a creature has the same removal score as a card that can exile a permanent. Certainly not the same in power.
I'd see the ratings more like something like this: Taken as an average for the following scores.
Removal method
Target Type
- 5: Permanent
4: Nonland permanent
3: Noncreature, nonland permanent
2: A Type (creature, land etc.)
1: A Subtype (goblin, Forest etc.)
Targets
- 5: All/Each opponent/s control
4: All/Each Target player controls
3: All/Each
2: Target
1: Target opponent controls
From the example in the wiki, Vindicate should only rank about 3-4, as it can only destroy, and it's only one permanent. Lightning Bolt would only rank 3 as it can only remove one creature by dealing damage (Red damage at that, Ghostfire should rate higher). Vindicate can't really be compared to Planar Cleansing, Obliterate, Devastation or Plague Wind as a score of 5.
Although really, I'd love to see the abilities of the cards themselves used as a removal value of some kind.
-
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, 10:13
I got this one wrong, didn't I? It needs to be "target nonblack creature defending player controls" but how? I didn't find a card without groovy code to copy from...
name=Throat Slitter
url=http://magiccards.info/query?q=!throat%20slitter
image=http://mtgimage.com/card/throat%20slitter.jpg
value=3.115
rarity=U
type=Creature
subtype=Rat,Ninja
cost={4}{B}
pt=2/2
ability=ninjutsu
{B};\
Whenever SN deals combat damage to a player, destroy target nonblack creature defending player controls.
timing=main
--------------
name=Throat Slitter
url=http://magiccards.info/query?q=!throat%20slitter
image=http://mtgimage.com/card/throat%20slitter.jpg
value=3.115
rarity=U
type=Creature
subtype=Rat,Ninja
cost={4}{B}
pt=2/2
ability=ninjutsu
{B}
timing=main
requires_groovy_code
[
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,
MagicTargetChoice.TARGET_NONBLACK_CREATURE_YOUR_OPPONENT_CONTROLS,
MagicDestroyTargetPicker.Destroy,
this,
"destroy target nonblack creature defending player controls."
):
MagicEvent.NONE;
}
@Override
public void executeEvent(final MagicGame game, final MagicEvent event) {
event.processTargetPermanent(game, {
final MagicPermanent permanent ->
game.doAction(new MagicDestroyAction(permanent));
});
}
}
]
name=Throat Slitter
url=http://magiccards.info/query?q=!throat%20slitter
image=http://mtgimage.com/card/throat%20slitter.jpg
value=3.115
rarity=U
type=Creature
subtype=Rat,Ninja
cost={4}{B}
pt=2/2
ability=ninjutsu

Whenever SN deals combat damage to a player, destroy target nonblack creature defending player controls.
timing=main
--------------
name=Throat Slitter
url=http://magiccards.info/query?q=!throat%20slitter
image=http://mtgimage.com/card/throat%20slitter.jpg
value=3.115
rarity=U
type=Creature
subtype=Rat,Ninja
cost={4}{B}
pt=2/2
ability=ninjutsu

timing=main
requires_groovy_code
[
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,
MagicTargetChoice.TARGET_NONBLACK_CREATURE_YOUR_OPPONENT_CONTROLS,
MagicDestroyTargetPicker.Destroy,
this,
"destroy target nonblack creature defending player controls."
):
MagicEvent.NONE;
}
@Override
public void executeEvent(final MagicGame game, final MagicEvent event) {
event.processTargetPermanent(game, {
final MagicPermanent permanent ->
game.doAction(new MagicDestroyAction(permanent));
});
}
}
]
Re: Card Contributions
by ShawnieBoy » 31 Mar 2014, 11:08
For Magarena, most 'defending player' and sometimes even 'all opponents' become target opponent - There's no multiplayer, so I can see why it's done.
As 'target nonblack creature your opponent controls' hasn't been implemented in the game engine, it doesn't mean you can't add it in a groovy script.
Have a look at the groovy code for Deus of Calamity and Inundate and see if anything clicks.
As 'target nonblack creature your opponent controls' hasn't been implemented in the game engine, it doesn't mean you can't add it in a groovy script.
Have a look at the groovy code for Deus of Calamity and Inundate and see if anything clicks.

-
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, 12:27
something like this?
name=Throat Slitter
url=http://magiccards.info/query?q=!throat%20slitter
image=http://mtgimage.com/card/throat%20slitter.jpg
value=3.115
rarity=U
type=Creature
subtype=Rat,Ninja
cost={4}{B}
pt=2/2
ability=ninjutsu
{B}
timing=main
requires_groovy_code
[
def NONBLACK_CREATURE_YOUR_OPPONENT_CONTROLS=new MagicPermanentFilterImpl() {
public boolean accept(final MagicGame game,final MagicPlayer player,final MagicPermanent target) {
return target.isCreature() && !target.hasColor(MagicColor.Black) && target.isOpponent(player);
}
}
def TARGET_NONBLACK_CREATURE_YOUR_OPPONENT_CONTROLS = new MagicTargetChoice(
NONBLACK_CREATURE_YOUR_OPPONENT_CONTROLS,
"a nonblack creature your opponent controls"
);
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,
MagicTargetChoice.TARGET_NONBLACK_CREATURE_YOUR_OPPONENT_CONTROLS,
MagicDestroyTargetPicker.Destroy,
this,
"destroy target nonblack creature defending player controls."
):
MagicEvent.NONE;
}
@Override
public void executeEvent(final MagicGame game, final MagicEvent event) {
event.processTargetPermanent(game, {
final MagicPermanent permanent ->
game.doAction(new MagicDestroyAction(permanent));
});
}
}
]
name=Throat Slitter
url=http://magiccards.info/query?q=!throat%20slitter
image=http://mtgimage.com/card/throat%20slitter.jpg
value=3.115
rarity=U
type=Creature
subtype=Rat,Ninja
cost={4}{B}
pt=2/2
ability=ninjutsu

timing=main
requires_groovy_code
[
def NONBLACK_CREATURE_YOUR_OPPONENT_CONTROLS=new MagicPermanentFilterImpl() {
public boolean accept(final MagicGame game,final MagicPlayer player,final MagicPermanent target) {
return target.isCreature() && !target.hasColor(MagicColor.Black) && target.isOpponent(player);
}
}
def TARGET_NONBLACK_CREATURE_YOUR_OPPONENT_CONTROLS = new MagicTargetChoice(
NONBLACK_CREATURE_YOUR_OPPONENT_CONTROLS,
"a nonblack creature your opponent controls"
);
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,
MagicTargetChoice.TARGET_NONBLACK_CREATURE_YOUR_OPPONENT_CONTROLS,
MagicDestroyTargetPicker.Destroy,
this,
"destroy target nonblack creature defending player controls."
):
MagicEvent.NONE;
}
@Override
public void executeEvent(final MagicGame game, final MagicEvent event) {
event.processTargetPermanent(game, {
final MagicPermanent permanent ->
game.doAction(new MagicDestroyAction(permanent));
});
}
}
]
Re: Card Contributions
by frank » 31 Mar 2014, 14:41
another try:
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
timing=main
requires_groovy_code
[
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,
MagicTargetChoice.TARGET_CREATURE_YOUR_OPPONENT_CONTROLS,
MagicBounceTargetPicker.create(),
this,
"return target creature defending player controls to its owner's hand."
):
MagicEvent.NONE;
}
@Override
public void executeEvent(final MagicGame game, final MagicEvent event) {
event.processTargetPermanent(game, {
final MagicPermanent permanent ->
game.doAction(new MagicRemoveFromPlayAction(creature,MagicLocationType.OwnersHand));
});
}
}
]
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

timing=main
requires_groovy_code
[
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,
MagicTargetChoice.TARGET_CREATURE_YOUR_OPPONENT_CONTROLS,
MagicBounceTargetPicker.create(),
this,
"return target creature defending player controls to its owner's hand."
):
MagicEvent.NONE;
}
@Override
public void executeEvent(final MagicGame game, final MagicEvent event) {
event.processTargetPermanent(game, {
final MagicPermanent permanent ->
game.doAction(new MagicRemoveFromPlayAction(creature,MagicLocationType.OwnersHand));
});
}
}
]
Re: Card Contributions
by frank » 31 Mar 2014, 18:49
well... this should create 2 events, which is not right, I suppose... better would be a devour-like may dialog.
name=Skullsnatcher
url=http://magiccards.info/query?q=!skullsnatcher
image=http://mtgimage.com/card/skullsnatcher.jpg
value=3.368
rarity=C
type=Creature
subtype=Rat,Ninja
cost={1}{B}
pt=1/1
ability=ninjutsu
timing=main
requires_groovy_code
[
new MagicWhenDamageIsDealtTrigger() {
@Override
public MagicEvent executeTrigger(final MagicGame game,final MagicPermanent permanent,final MagicDamage damage) {
return (damage.getSource() == permanent &&
damage.getTarget().isPlayer() &&
damage.isCombat()) ?
for(int i=1;i<=2;i++){
new MagicEvent(
permanent,
new MagicMayChoice(
MagicTargetChoice.TARGET_CREATURE_CARD_FROM_GRAVEYARD,
MagicGraveyardTargetPicker.ExileOpp,
this,
"exile target card from a graveyard"))}:
MagicEvent.NONE;
}
@Override
public void executeEvent(final MagicGame game, final MagicEvent event) {
event.processTargetPermanent(game, {
final MagicPermanent card ->
game.doAction(new MagicRemoveCardAction(
card,
MagicLocationType.Graveyard));
game.doAction(new MagicMoveCardAction(
card,
MagicLocationType.Graveyard,
MagicLocationType.Exile));
});
}
}
]
name=Skullsnatcher
url=http://magiccards.info/query?q=!skullsnatcher
image=http://mtgimage.com/card/skullsnatcher.jpg
value=3.368
rarity=C
type=Creature
subtype=Rat,Ninja
cost={1}{B}
pt=1/1
ability=ninjutsu

timing=main
requires_groovy_code
[
new MagicWhenDamageIsDealtTrigger() {
@Override
public MagicEvent executeTrigger(final MagicGame game,final MagicPermanent permanent,final MagicDamage damage) {
return (damage.getSource() == permanent &&
damage.getTarget().isPlayer() &&
damage.isCombat()) ?
for(int i=1;i<=2;i++){
new MagicEvent(
permanent,
new MagicMayChoice(
MagicTargetChoice.TARGET_CREATURE_CARD_FROM_GRAVEYARD,
MagicGraveyardTargetPicker.ExileOpp,
this,
"exile target card from a graveyard"))}:
MagicEvent.NONE;
}
@Override
public void executeEvent(final MagicGame game, final MagicEvent event) {
event.processTargetPermanent(game, {
final MagicPermanent card ->
game.doAction(new MagicRemoveCardAction(
card,
MagicLocationType.Graveyard));
game.doAction(new MagicMoveCardAction(
card,
MagicLocationType.Graveyard,
MagicLocationType.Exile));
});
}
}
]
Re: Card Contributions
by ShawnieBoy » 31 Mar 2014, 21:50
Good work Frank
I'll go through Throat Slitter, then look at the other ones afterwards.
Glad you worked out how to define the new targetChoice!
There's a couple of minor issues with the code (you've probably found that out already, trying to test it).
Anything that's defined (def) needs to be outside of the main square brackets for the ability/effect/trigger. As you've already defined that TARGET_NONBLACK_CREATURE_YOUR_OPPONENT_CONTROLS is a MagicTargetChoice, you do not need a MagicTargetChoice. prefix for it. That's only for calling what's already in the game engine. There was also a missing ';' after the first def block - but a great first submission! Keep 'em coming.
Here's the code with the edits in the groovy:
You can put these in your scripts folder and play with your creation
(.groovy is just a renamed .txt)

Glad you worked out how to define the new targetChoice!
There's a couple of minor issues with the code (you've probably found that out already, trying to test it).
Anything that's defined (def) needs to be outside of the main square brackets for the ability/effect/trigger. As you've already defined that TARGET_NONBLACK_CREATURE_YOUR_OPPONENT_CONTROLS is a MagicTargetChoice, you do not need a MagicTargetChoice. prefix for it. That's only for calling what's already in the game engine. There was also a missing ';' after the first def block - but a great first submission! Keep 'em coming.
Here's the code with the edits in the groovy:
- Code: Select all
name=Throat Slitter
url=http://magiccards.info/query?q=!throat%20slitter
image=http://mtgimage.com/card/throat%20slitter.jpg
value=3.115
rarity=U
type=Creature
subtype=Rat,Ninja
cost={4}{B}
pt=2/2
ability=ninjutsu {2}{B}
timing=main
requires_groovy_code
- Code: Select all
def NONBLACK_CREATURE_YOUR_OPPONENT_CONTROLS=new MagicPermanentFilterImpl() {
public boolean accept(final MagicGame game,final MagicPlayer player,final MagicPermanent target) {
return target.isCreature() && !target.hasColor(MagicColor.Black) && target.isOpponent(player);
}
};
def TARGET_NONBLACK_CREATURE_YOUR_OPPONENT_CONTROLS = new MagicTargetChoice(
NONBLACK_CREATURE_YOUR_OPPONENT_CONTROLS,
"a nonblack creature your opponent controls"
);
[
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,
TARGET_NONBLACK_CREATURE_YOUR_OPPONENT_CONTROLS,
MagicDestroyTargetPicker.Destroy,
this,
"Destroy target nonblack creature defending player controls."
):
MagicEvent.NONE;
}
@Override
public void executeEvent(final MagicGame game, final MagicEvent event) {
event.processTargetPermanent(game, {
final MagicPermanent permanent ->
game.doAction(new MagicDestroyAction(permanent));
});
}
}
]
You can put these in your scripts folder and play with your creation

-
ShawnieBoy - Programmer
- Posts: 601
- Joined: 02 Apr 2012, 22:42
- Location: UK
- Has thanked: 80 times
- Been thanked: 50 times
Who is online
Users browsing this forum: No registered users and 1 guest