Merge branch 'illusionary_terrain' into 'master'

Illusionary Terrain

See merge request core-developers/forge!3636
This commit is contained in:
Michael Kamensky
2021-01-25 04:47:57 +00:00
11 changed files with 68 additions and 1 deletions

View File

@@ -76,6 +76,7 @@ public abstract class GameState {
private final Map<Card, List<String>> cardToChosenClrs = new HashMap<>();
private final Map<Card, CardCollection> cardToChosenCards = new HashMap<>();
private final Map<Card, String> cardToChosenType = new HashMap<>();
private final Map<Card, String> cardToChosenType2 = new HashMap<>();
private final Map<Card, List<String>> cardToRememberedId = new HashMap<>();
private final Map<Card, List<String>> cardToImprintedId = new HashMap<>();
private final Map<Card, String> cardToNamedCard = new HashMap<>();
@@ -323,6 +324,9 @@ public abstract class GameState {
if (!c.getChosenType().isEmpty()) {
newText.append("|ChosenType:").append(c.getChosenType());
}
if (!c.getChosenType2().isEmpty()) {
newText.append("|ChosenType2:").append(c.getChosenType2());
}
if (!c.getNamedCard().isEmpty()) {
newText.append("|NamedCard:").append(c.getNamedCard());
}
@@ -601,6 +605,7 @@ public abstract class GameState {
cardToChosenClrs.clear();
cardToChosenCards.clear();
cardToChosenType.clear();
cardToChosenType2.clear();
cardToScript.clear();
cardAttackMap.clear();
@@ -1055,6 +1060,12 @@ public abstract class GameState {
c.setChosenType(entry.getValue());
}
// Chosen type 2
for (Entry<Card, String> entry : cardToChosenType2.entrySet()) {
Card c = entry.getKey();
c.setChosenType2(entry.getValue());
}
// Named card
for (Entry<Card, String> entry : cardToNamedCard.entrySet()) {
Card c = entry.getKey();
@@ -1286,6 +1297,8 @@ public abstract class GameState {
cardToChosenClrs.put(c, Arrays.asList(info.substring(info.indexOf(':') + 1).split(",")));
} else if (info.startsWith("ChosenType:")) {
cardToChosenType.put(c, info.substring(info.indexOf(':') + 1));
} else if (info.startsWith("ChosenType2:")) {
cardToChosenType2.put(c, info.substring(info.indexOf(':') + 1));
} else if (info.startsWith("ChosenCards:")) {
CardCollection chosen = new CardCollection();
String[] idlist = info.substring(info.indexOf(':') + 1).split(",");

View File

@@ -336,6 +336,9 @@ public class GameCopier {
if (!c.getChosenType().isEmpty()) {
newCard.setChosenType(c.getChosenType());
}
if (!c.getChosenType2().isEmpty()) {
newCard.setChosenType2(c.getChosenType2());
}
if (c.getChosenColors() != null) {
newCard.setChosenColors(Lists.newArrayList(c.getChosenColors()));
}

View File

@@ -73,6 +73,10 @@ public class ForgeScript {
return cardState.getTypeWithChanges().hasStringType(source.getChosenType());
} else if (property.equals("IsNotChosenType")) {
return !cardState.getTypeWithChanges().hasStringType(source.getChosenType());
} else if (property.equals("ChosenType2")) {
return cardState.getTypeWithChanges().hasStringType(source.getChosenType2());
} else if (property.equals("IsNotChosenType2")) {
return !cardState.getTypeWithChanges().hasStringType(source.getChosenType2());
} else if (property.startsWith("HasSubtype")) {
final String subType = property.substring(11);
return cardState.getTypeWithChanges().hasSubtype(subType);

View File

@@ -64,7 +64,11 @@ public class ChooseTypeEffect extends SpellAbilityEffect {
for (final Player p : tgtPlayers) {
if ((tgt == null) || p.canBeTargetedBy(sa)) {
String choice = p.getController().chooseSomeType(type, sa, validTypes, invalidTypes);
card.setChosenType(choice);
if (!sa.hasParam("Secondary")) {
card.setChosenType(choice);
} else {
card.setChosenType2(choice);
}
}
}
}

View File

@@ -53,6 +53,7 @@ public class CleanUpEffect extends SpellAbilityEffect {
}
if (sa.hasParam("ClearChosenType")) {
source.setChosenType("");
source.setChosenType2("");
}
if (sa.hasParam("ClearChosenColor")) {
source.setChosenColors(null);

View File

@@ -228,6 +228,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
private String originalText = "", text = "";
private String chosenType = "";
private String chosenType2 = "";
private List<String> chosenColors;
private String chosenName = "";
private String chosenName2 = "";
@@ -1469,6 +1470,20 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
return chosenType != null && !chosenType.isEmpty();
}
// used by card Illusionary Terrain
public final String getChosenType2() {
return chosenType2;
}
public final void setChosenType2(final String s) {
chosenType2 = s;
view.updateChosenType2(this);
}
public final boolean hasChosenType2() {
return chosenType2 != null && !chosenType2.isEmpty();
}
public final String getChosenColor() {
if (hasChosenColor()) {
return chosenColors.get(0);

View File

@@ -306,6 +306,13 @@ public class CardView extends GameEntityView {
set(TrackableProperty.ChosenType, c.getChosenType());
}
public String getChosenType2() {
return get(TrackableProperty.ChosenType2);
}
void updateChosenType2(Card c) {
set(TrackableProperty.ChosenType2, c.getChosenType2());
}
public String getChosenNumber() {
return get(TrackableProperty.ChosenNumber);
}

View File

@@ -367,6 +367,9 @@ public final class StaticAbilityContinuous {
if (input.equals("ChosenType") && !hostCard.hasChosenType()) {
return true;
}
if (input.equals("ChosenType2") && !hostCard.hasChosenType2()) {
return true;
}
if (input.equals("ImprintedCreatureType")) {
if (hostCard.hasImprintedCard()) {
newTypes.addAll(hostCard.getImprintedCards().getLast().getType().getCreatureTypes());
@@ -385,6 +388,9 @@ public final class StaticAbilityContinuous {
addTypes = Lists.transform(addTypes, new Function<String, String>() {
@Override
public String apply(String input) {
if (hostCard.hasChosenType2()) {
input = input.replaceAll("ChosenType2", hostCard.getChosenType2());
}
if (hostCard.hasChosenType()) {
input = input.replaceAll("ChosenType", hostCard.getChosenType());
}

View File

@@ -48,6 +48,7 @@ public enum TrackableProperty {
LethalDamage(TrackableTypes.IntegerType),
ShieldCount(TrackableTypes.IntegerType),
ChosenType(TrackableTypes.StringType),
ChosenType2(TrackableTypes.StringType),
ChosenColors(TrackableTypes.StringListType),
ChosenCards(TrackableTypes.CardViewCollectionType),
ChosenNumber(TrackableTypes.StringType),

View File

@@ -0,0 +1,10 @@
Name:Illusionary Terrain
ManaCost:U U
Types:Enchantment
K:Cumulative upkeep:2
T:Mode$ ChangesZone | ValidCard$ Card.Self | Origin$ Any | Destination$ Battlefield | Execute$ TrigChooseType1 | TriggerDescription$ As Illusionary Terrain enters the battlefield, choose two basic land types.
SVar:TrigChooseType1:DB$ ChooseType | Defined$ You | Type$ Basic Land | SubAbility$ ChooseType2
SVar:ChooseType2:DB$ ChooseType | Defined$ You | Type$ Basic Land | Secondary$ True
S:Mode$ Continuous | Affected$ Land.Basic+ChosenType | AddType$ ChosenType2 | RemoveLandTypes$ True | Description$ Basic lands of the first chosen type are the second chosen type.
AI:RemoveDeck:All
Oracle:Cumulative upkeep {2} (At the beginning of your upkeep, put an age counter on this permanent, then sacrifice it unless you pay its upkeep cost for each age counter on it.)\nAs Illusionary Terrain enters the battlefield, choose two basic land types.\nBasic lands of the first chosen type are the second chosen type.

View File

@@ -393,6 +393,9 @@ public class CardDetailUtil {
}
area.append("(chosen type: ");
area.append(card.getChosenType());
if (!card.getChosenType2().isEmpty()) {
area.append(", ").append(card.getChosenType2());
}
area.append(")");
}