Merge branch 'ludevic' into 'master'

MID: Ludevic and (lots of) support

See merge request core-developers/forge!5387
This commit is contained in:
Michael Kamensky
2021-09-21 04:06:23 +00:00
7 changed files with 97 additions and 8 deletions

View File

@@ -594,7 +594,10 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
rebuildMutatedStates(cause); rebuildMutatedStates(cause);
} }
// do the Transform trigger there, it can also happen if the resulting state doesn't change // run valid Replacement here
getGame().getReplacementHandler().run(ReplacementType.Transform, AbilityKey.mapFromAffected(this));
// do the Transform trigger here, it can also happen if the resulting state doesn't change
// Clear old dfc trigger from the trigger handler // Clear old dfc trigger from the trigger handler
getGame().getTriggerHandler().clearActiveTriggers(this, null); getGame().getTriggerHandler().clearActiveTriggers(this, null);
getGame().getTriggerHandler().registerActiveTrigger(this, false); getGame().getTriggerHandler().registerActiveTrigger(this, false);

View File

@@ -21,6 +21,7 @@ import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.Set;
import com.google.common.base.Function; import com.google.common.base.Function;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
@@ -28,12 +29,7 @@ import com.google.common.collect.Lists;
import forge.ImageKeys; import forge.ImageKeys;
import forge.StaticData; import forge.StaticData;
import forge.card.CardRules; import forge.card.*;
import forge.card.CardSplitType;
import forge.card.CardStateName;
import forge.card.CardType;
import forge.card.ICardFace;
import forge.card.MagicColor;
import forge.card.mana.ManaCost; import forge.card.mana.ManaCost;
import forge.game.CardTraitBase; import forge.game.CardTraitBase;
import forge.game.Game; import forge.game.Game;
@@ -601,6 +597,11 @@ public class CardFactory {
keywords.addAll(Arrays.asList(sa.getParam("AddKeywords").split(" & "))); keywords.addAll(Arrays.asList(sa.getParam("AddKeywords").split(" & ")));
} }
if (sa.hasParam("AddColors")) {
shortColors = CardUtil.getShortColorsString(Arrays.asList(sa.getParam("AddColors")
.split(" & ")));
}
if (sa.hasParam("RemoveKeywords")) { if (sa.hasParam("RemoveKeywords")) {
removeKeywords.addAll(Arrays.asList(sa.getParam("RemoveKeywords").split(" & "))); removeKeywords.addAll(Arrays.asList(sa.getParam("RemoveKeywords").split(" & ")));
} }
@@ -657,6 +658,10 @@ public class CardFactory {
state.setName(newName); state.setName(newName);
} }
if (sa.hasParam("AddColors")) {
state.addColor(shortColors);
}
if (sa.hasParam("SetColor")) { if (sa.hasParam("SetColor")) {
state.setColor(shortColors); state.setColor(shortColors);
} }

View File

@@ -166,6 +166,15 @@ public class CardState extends GameObject implements IHasSVars {
public final byte getColor() { public final byte getColor() {
return color; return color;
} }
public final void addColor(final String color) {
final ManaCostParser parser = new ManaCostParser(color);
final ManaCost cost = new ManaCost(parser);
addColor(cost.getColorProfile());
}
public final void addColor(final byte color) {
this.color |= color;
view.updateColors(card);
}
public final void setColor(final String color) { public final void setColor(final String color) {
final ManaCostParser parser = new ManaCostParser(color); final ManaCostParser parser = new ManaCostParser(color);
final ManaCost cost = new ManaCost(parser); final ManaCost cost = new ManaCost(parser);

View File

@@ -101,7 +101,7 @@ public class CostExile extends CostPartWithList {
return String.format("Exile %s", Cost.convertAmountTypeToWords(i, this.getAmount(), desc)); return String.format("Exile %s", Cost.convertAmountTypeToWords(i, this.getAmount(), desc));
} }
if (!desc.equals("Card") && !desc.endsWith("card")) { if (!desc.equals("Card") && !desc.contains("card")) {
if (this.sameZone) { if (this.sameZone) {
return String.format("Exile card %s from the same %s", Cost.convertAmountTypeToWords(i, this.getAmount(), desc), origin); return String.format("Exile card %s from the same %s", Cost.convertAmountTypeToWords(i, this.getAmount(), desc), origin);
} }

View File

@@ -0,0 +1,44 @@
package forge.game.replacement;
import java.util.Map;
import forge.game.ability.AbilityKey;
import forge.game.card.Card;
import forge.game.spellability.SpellAbility;
/**
* TODO: Write javadoc for this type.
*
*/
public class ReplaceTransform extends ReplacementEffect {
/**
*
* TODO: Write javadoc for Constructor.
* @param mapParams &emsp; HashMap<String, String>
* @param host &emsp; Card
*/
public ReplaceTransform(final Map<String, String> mapParams, final Card host, final boolean intrinsic) {
super(mapParams, host, intrinsic);
}
/* (non-Javadoc)
* @see forge.card.replacement.ReplacementEffect#canReplace(java.util.HashMap)
*/
@Override
public boolean canReplace(Map<AbilityKey, Object> runParams) {
if (!matchesValidParam("ValidCard", runParams.get(AbilityKey.Affected))) {
return false;
}
return true;
}
/* (non-Javadoc)
* @see forge.card.replacement.ReplacementEffect#setReplacingObjects(java.util.HashMap, forge.card.spellability.SpellAbility)
*/
@Override
public void setReplacingObjects(Map<AbilityKey, Object> runParams, SpellAbility sa) {
sa.setReplacingObject(AbilityKey.Card, runParams.get(AbilityKey.Affected));
}
}

View File

@@ -37,6 +37,7 @@ public enum ReplacementType {
SetInMotion(ReplaceSetInMotion.class), SetInMotion(ReplaceSetInMotion.class),
Surveil(ReplaceSurveil.class), Surveil(ReplaceSurveil.class),
Tap(ReplaceTap.class), Tap(ReplaceTap.class),
Transform(ReplaceTransform.class),
TurnFaceUp(ReplaceTurnFaceUp.class), TurnFaceUp(ReplaceTurnFaceUp.class),
Untap(ReplaceUntap.class); Untap(ReplaceUntap.class);

View File

@@ -0,0 +1,27 @@
Name:Ludevic, Necrogenius
ManaCost:U B
Types:Legendary Creature Human Wizard
PT:2/3
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigMill | TriggerDescription$ Whenever CARDNAME enters the battlefield or attacks, mill a card.
T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigMill | Secondary$ True | TriggerDescription$ Whenever CARDNAME enters the battlefield or attacks, mill a card.
SVar:TrigMill:DB$ Mill | NumCards$ 1 | Defined$ You
A:AB$ SetState | Cost$ XCantBe0 X U U B B ExileFromGrave<X/Creature/creature cards> | Defined$ Self | Mode$ Transform | SorcerySpeed$ True | SpellDescription$ Transform CARDNAME. X can't be zero. Activate only as a sorcery.
AlternateMode:DoubleFaced
SVar:X:Count$xPaid
DeckHas:Ability$Mill
DeckHints:Ability$Graveyard
Oracle:Whenever Ludevic, Necrogenius enters the battlefield or attacks, mill a card.\n{X}{U}{U}{B}{B}, Exile X creature cards from your graveyard: Transform Ludevic, Necrogenius. X can't be zero. Activate only as a sorcery.
ALTERNATE
Name:Olag, Ludevic's Hubris
ManaCost:no cost
Colors:blue,black
Types:Legendary Creature Zombie
PT:4/4
R:Event$ Transform | ValidCard$ Card.Self | ReplaceWith$ Copy | Description$ As this creature transforms into CARDNAME, it becomes a copy of a creature card exiled with it, except its name is Olag, Ludevics Hubris, it's 4/4, and it's a legendary blue and black Zombie in addition to its other colors and types. Put a number of +1/+1 counters on NICKNAME equal to the number of creature cards exiled with it.
SVar:Copy:DB$ Clone | Choices$ Creature.ExiledWithSource | ChoiceZone$ Exile | NewName$ Olag, Ludevic's Hubris | SetPower$ 4 | SetToughness$ 4 | AddTypes$ Legendary & Zombie | AddColors$ Blue & Black | SubAbility$ DBPutCounter
SVar:DBPutCounter:DB$ PutCounter | CounterNum$ Y | CounterType$ P1P1
SVar:Y:Count$ValidExile Creature.ExiledWithSource
DeckHas:Ability$Counters
Oracle:As this creature transforms into Olag, Ludevic's Hubris, it becomes a copy of a creature card exiled with it, except its name is Olag, Ludevic's Hubris, it's 4/4, and it's a legendary blue and black Zombie in addition to its other colors and types. Put a number of +1/+1 counters on Olag equal to the number of creature cards exiled with it.