Question about replacement effects
Post MTG Forge Related Programming Questions Here
Moderators: timmermac, Blacksmith, KrazyTheFox, Agetian, friarsol, CCGHQ Admins
3 posts
• Page 1 of 1
Question about replacement effects
by moomarc » 07 Feb 2013, 17:24
I've been trying to add Bloodlord of Vaasgoth today and haven't been able to get one last bit right. Basically he pumps another one of those cardFactoryUtil keywords that are unpumpable (at least not so that they're effective), namely Bloodthirst.
So I had to script the various parts of the keyword and had to add some small bits of code as I went along. The basic script is:
I suppose this is why animate didn't add replacement effects already, but I'm still curious as to why it happens.
(If you're wondering why I compare the replacement string; it seems that when addReplacement is called, a copy of the parsed replacement is created which is then added to the card. I tested and the original ReplacementEffect != card.getReplacementEffects().get(0) (assuming there is just the one replacement). So I decided to campare the strings and remove the first instance of it and I could finally start removing the intended replacement effects - unfortunately that just didn't help!)
Anyway, if I can get this working I should be able to crack the other cards that try pump those keywords.
So I had to script the various parts of the keyword and had to add some small bits of code as I went along. The basic script is:
- Script | Open
- Code: Select all
K:Bloodthirst 3
K:Flying
T:Mode$ SpellCast | ValidCard$ Creature.Vampire | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ BloodPump | TriggerDescription$ Whenever you cast a Vampire creature spell, it gains bloodthirst 3.
SVar:BloodPump:AB$ Animate | Cost$ 0 | Defined$ TriggeredCard | Replacements$ etbBloodthirst | sVars$ BloodthirstETB,BloodthirstCounters | UntilLeavesPlay$ True | PumpZone$ Stack
SVar:etbBloodthirst:Event$ Moved | ValidCard$ Card.Self | Destination$ Battlefield | Bloodthirst$ True | ReplaceWith$ BloodthirstETB | Description$ Bloodthirst 3 (If an opponent was dealt damage this turn, this creature enters the battlefield with three +1/+1 counters on it.)
SVar:BloodthirstETB:AB$ ChangeZone | Cost$ 0 | Hidden$ True | Origin$ All | Destination$ Battlefield | Defined$ ReplacedCard | SubAbility$ BloodthirstCounters
SVar:BloodthirstCounters:DB$ PutCounter | Defined$ Self | CounterType$ P1P1 | CounterNum$ 3
- Animate.java | Open
- Code: Select all
// replacement effects to add to the animated being
final ArrayList<String> replacements = new ArrayList<String>();
if (sa.hasParam("Replacements")) {
replacements.addAll(Arrays.asList(sa.getParam("Replacements").split(",")));
}
- Code: Select all
...then later when applying the various bits of Animate:
// give replacement effects
final ArrayList<ReplacementEffect> addedReplacements = new ArrayList<ReplacementEffect>();
if (replacements.size() > 0) {
for (final String s : replacements) {
final String actualReplacement = host.getSVar(s);
final ReplacementEffect parsedReplacement = ReplacementHandler.parseReplacement(actualReplacement, c);
c.addReplacementEffect(parsedReplacement);
addedReplacements.add(parsedReplacement);
}
}
- Code: Select all
...Then in the unanimate command:
// remove added replacement effects
for (final ReplacementEffect originalRE : addedReplacements) {
int index = -1;
// Card.addReplacementEffect adds a copy of the effect so need to find matching repl. effect
for (final ReplacementEffect copyOnCard : c.getReplacementEffects()) {
if ((copyOnCard.toString()).equals(originalRE.toString())) {
index = c.getReplacementEffects().indexOf(copyOnCard);
break;
}
}
if (index != -1) {
c.getReplacementEffects().get(index).setSuppressed(true);
}
}
- Code: Select all
...One last bit to cover any external factors; in unanimate:
} else if (sa.hasParam("UntilLeavesPlay")) {
c.addLeavesPlayCommand(unanimate);

](./images/smilies/eusa_wall.gif)
I suppose this is why animate didn't add replacement effects already, but I'm still curious as to why it happens.

(If you're wondering why I compare the replacement string; it seems that when addReplacement is called, a copy of the parsed replacement is created which is then added to the card. I tested and the original ReplacementEffect != card.getReplacementEffects().get(0) (assuming there is just the one replacement). So I decided to campare the strings and remove the first instance of it and I could finally start removing the intended replacement effects - unfortunately that just didn't help!)
Anyway, if I can get this working I should be able to crack the other cards that try pump those keywords.
-Marc
-
moomarc - Pixel Commander
- Posts: 2091
- Joined: 04 Jun 2010, 15:22
- Location: Johannesburg, South Africa
- Has thanked: 371 times
- Been thanked: 372 times
Re: Question about replacement effects
by moomarc » 11 Feb 2013, 15:46
Hmmm. Previous post didn't get anywhere so on to the next topic... I want to convert Dodecapod and friends to proper replacement effects so that they interact properly with Library of Leng (and hopefully I'll also manage Madness). The converted Dodecapod is working perfectly, but using the replacement effect instead of the keyword bypasses the check for good discard candidates in DiscardEffect.java, and I obviously don't want to convert something that makes the AI worse. So how do I check for a specific replacement effect type ("Discard" obviously)?
-Marc
-
moomarc - Pixel Commander
- Posts: 2091
- Joined: 04 Jun 2010, 15:22
- Location: Johannesburg, South Africa
- Has thanked: 371 times
- Been thanked: 372 times
Re: Question about replacement effects
by Sloth » 11 Feb 2013, 21:23
Technically Dodecapod doesn't have any discard AI attached, because the keyword differs to the keyword of Loxodon Smiter. Predicting replacement effects is rather laborious, prone to syntax changes and has the danger of causing NPE's. Just add a new SVar DiscardMeByOpp for cards like Dodecapod, Guerrilla Tactics, Psychic Purge and Metrognome.moomarc wrote:Hmmm. Previous post didn't get anywhere so on to the next topic... I want to convert Dodecapod and friends to proper replacement effects so that they interact properly with Library of Leng (and hopefully I'll also manage Madness). The converted Dodecapod is working perfectly, but using the replacement effect instead of the keyword bypasses the check for good discard candidates in DiscardEffect.java, and I obviously don't want to convert something that makes the AI worse. So how do I check for a specific replacement effect type ("Discard" obviously)?
-
Sloth - Programmer
- Posts: 3498
- Joined: 23 Jun 2009, 19:40
- Has thanked: 125 times
- Been thanked: 507 times
3 posts
• Page 1 of 1
Who is online
Users browsing this forum: No registered users and 29 guests