mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-15 02:08:00 +00:00
CLB: Volo, Journal, support, etc. (#1211)
* volo_itinerant_scholar.txt * volos_journal.txt * TrackableProperty.NotedTypes * ChooseTypeEffect.resolve implement "TypesFromDefined" * ChooseTypeEffect.resolve implement "Note" * CardView.getNotedTypes / CardView.updateNotedTypes * CardDetailUtil.composeCardText add noted type area * Card.java implement notedTypes * AbilityUtils.xCount "CardNumNotedTypes"
This commit is contained in:
@@ -12,16 +12,12 @@ import java.util.Map.Entry;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import com.google.common.collect.*;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
import forge.card.CardStateName;
|
||||
import forge.card.CardType;
|
||||
@@ -2046,6 +2042,10 @@ public class AbilityUtils {
|
||||
return doXMath(ce == null ? 0 : getNumberOfTypes(ce), expr, c, ctb);
|
||||
}
|
||||
|
||||
if (sq[0].contains("CardNumNotedTypes")) {
|
||||
return doXMath(c.getNumNotedTypes(), expr, c, ctb);
|
||||
}
|
||||
|
||||
if (sq[0].contains("CardNumColors")) {
|
||||
return doXMath(c.getColor().countColors(), expr, c, ctb);
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import forge.card.CardType;
|
||||
import forge.game.ability.AbilityUtils;
|
||||
import forge.game.ability.SpellAbilityEffect;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.player.Player;
|
||||
@@ -49,7 +50,17 @@ public class ChooseTypeEffect extends SpellAbilityEffect {
|
||||
validTypes.addAll(CardType.getAllCardTypes());
|
||||
break;
|
||||
case "Creature":
|
||||
validTypes.addAll(CardType.getAllCreatureTypes());
|
||||
if (sa.hasParam("TypesFromDefined")) {
|
||||
for (final Card c : AbilityUtils.getDefinedCards(card, sa.getParam("TypesFromDefined"), sa)) {
|
||||
for (String t : c.getType()) {
|
||||
if (CardType.isACreatureType(t)) {
|
||||
validTypes.add(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
validTypes.addAll(CardType.getAllCreatureTypes());
|
||||
}
|
||||
break;
|
||||
case "Basic Land":
|
||||
validTypes.addAll(CardType.getBasicTypes());
|
||||
@@ -75,10 +86,17 @@ public class ChooseTypeEffect extends SpellAbilityEffect {
|
||||
for (final String s : invalidTypes) {
|
||||
validTypes.remove(s);
|
||||
}
|
||||
if (sa.hasParam("Note") && card.hasAnyNotedType()) {
|
||||
for (String noted : card.getNotedTypes()) {
|
||||
validTypes.remove(noted);
|
||||
}
|
||||
}
|
||||
|
||||
final TargetRestrictions tgt = sa.getTargetRestrictions();
|
||||
|
||||
if (!validTypes.isEmpty()) {
|
||||
if (validTypes.isEmpty() && sa.hasParam("Note")) {
|
||||
// OK to end up with no choices/have nothing new to note
|
||||
} else if (!validTypes.isEmpty()) {
|
||||
for (final Player p : tgtPlayers) {
|
||||
String choice;
|
||||
if ((tgt == null) || p.canBeTargetedBy(sa)) {
|
||||
@@ -89,7 +107,9 @@ public class ChooseTypeEffect extends SpellAbilityEffect {
|
||||
} else {
|
||||
choice = p.getController().chooseSomeType(type, sa, validTypes, invalidTypes);
|
||||
}
|
||||
if (!sa.hasParam("ChooseType2")) {
|
||||
if (sa.hasParam("Note")) {
|
||||
card.addNotedType(choice);
|
||||
} else if (!sa.hasParam("ChooseType2")) {
|
||||
card.setChosenType(choice);
|
||||
} else {
|
||||
card.setChosenType2(choice);
|
||||
|
||||
@@ -276,6 +276,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
||||
private String originalText = "", text = "";
|
||||
private String chosenType = "";
|
||||
private String chosenType2 = "";
|
||||
private List<String> notedTypes = new ArrayList<>();
|
||||
private List<String> chosenColors;
|
||||
private String chosenName = "";
|
||||
private String chosenName2 = "";
|
||||
@@ -1745,6 +1746,29 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
||||
return chosenType2 != null && !chosenType2.isEmpty();
|
||||
}
|
||||
|
||||
public final boolean hasAnyNotedType() {
|
||||
return notedTypes != null && !notedTypes.isEmpty();
|
||||
}
|
||||
|
||||
public final void addNotedType(final String type) {
|
||||
notedTypes.add(type);
|
||||
view.updateNotedTypes(this);
|
||||
}
|
||||
|
||||
public final Iterable<String> getNotedTypes() {
|
||||
if (notedTypes == null) {
|
||||
return Lists.newArrayList();
|
||||
}
|
||||
return notedTypes;
|
||||
}
|
||||
|
||||
public final int getNumNotedTypes() {
|
||||
if (notedTypes == null) {
|
||||
return 0;
|
||||
}
|
||||
return notedTypes.size();
|
||||
}
|
||||
|
||||
public final String getChosenColor() {
|
||||
if (hasChosenColor()) {
|
||||
return chosenColors.get(0);
|
||||
|
||||
@@ -359,6 +359,13 @@ public class CardView extends GameEntityView {
|
||||
set(TrackableProperty.ChosenType2, c.getChosenType2());
|
||||
}
|
||||
|
||||
public List<String> getNotedTypes() {
|
||||
return get(TrackableProperty.NotedTypes);
|
||||
}
|
||||
void updateNotedTypes(Card c) {
|
||||
set(TrackableProperty.NotedTypes, c.getNotedTypes());
|
||||
}
|
||||
|
||||
public String getChosenNumber() {
|
||||
return get(TrackableProperty.ChosenNumber);
|
||||
}
|
||||
|
||||
@@ -59,6 +59,7 @@ public enum TrackableProperty {
|
||||
ShieldCount(TrackableTypes.IntegerType),
|
||||
ChosenType(TrackableTypes.StringType),
|
||||
ChosenType2(TrackableTypes.StringType),
|
||||
NotedTypes(TrackableTypes.StringListType),
|
||||
ChosenColors(TrackableTypes.StringListType),
|
||||
ChosenCards(TrackableTypes.CardViewCollectionType),
|
||||
ChosenNumber(TrackableTypes.StringType),
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
Name:Volo, Itinerant Scholar
|
||||
ManaCost:2 U
|
||||
Types:Legendary Creature Human Wizard
|
||||
PT:2/3
|
||||
T:Mode$ ChangesZone | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigToken | TriggerDescription$ When NICKNAME enters the battlefield, create Volo's Journal, a legendary colorless artifact token with hexproof and "Whenever you cast a creature spell, note one of its creature types that hasn't been noted for this artifact."
|
||||
SVar:TrigToken:DB$ Token | TokenScript$ volos_journal
|
||||
A:AB$ Pump | Cost$ 2 T | ValidTgts$ Permanent.namedVolo's Journal+YouCtrl | TgtPrompt$ Select target permanent you control named Volo's Journal | SubAbility$ DBDraw | StackDescription$ None | SpellDescription$ Draw a card for each creature type noted for target permanent you control named Volo's Journal.
|
||||
SVar:DBDraw:DB$ Draw | NumCards$ X
|
||||
SVar:X:Targeted$CardNumNotedTypes
|
||||
K:Choose a Background
|
||||
DeckHas:Ability$Token & Type$Artifact
|
||||
Oracle:When Volo enters the battlefield, create Volo's Journal, a legendary colorless artifact token with hexproof and "Whenever you cast a creature spell, note one of its creature types that hasn't been noted for this artifact."\n{2}, {T}: Draw a card for each creature type noted for target permanent you control named Volo's Journal.\nChoose a Background
|
||||
7
forge-gui/res/tokenscripts/volos_journal.txt
Normal file
7
forge-gui/res/tokenscripts/volos_journal.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
Name:Volo's Journal
|
||||
ManaCost:no cost
|
||||
Types:Legendary Artifact
|
||||
K:Hexproof
|
||||
T:Mode$ SpellCast | ValidCard$ Creature | ValidActivatingPlayer$ You | Execute$ TrigNoteType | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast a creature spell, note one of its creature types that hasn't been noted for this artifact.
|
||||
SVar:TrigNoteType:DB$ ChooseType | Type$ Creature | TypesFromDefined$ TriggeredCard | Note$ True
|
||||
Oracle:Hexproof\nWhenever you cast a creature spell, note one of its creature types that hasn't been noted for this artifact.
|
||||
@@ -419,6 +419,16 @@ public class CardDetailUtil {
|
||||
area.append(")");
|
||||
}
|
||||
|
||||
// noted types
|
||||
if (card.getNotedTypes() != null && !card.getNotedTypes().isEmpty()) {
|
||||
if (area.length() != 0) {
|
||||
area.append("\n");
|
||||
}
|
||||
area.append("(noted type").append(card.getNotedTypes().size() == 1 ? ": " : "s: ");
|
||||
area.append(Lang.joinHomogenous(card.getNotedTypes()));
|
||||
area.append(")");
|
||||
}
|
||||
|
||||
// chosen color
|
||||
if (card.getChosenColors() != null && !card.getChosenColors().isEmpty()) {
|
||||
if (area.length() != 0) {
|
||||
|
||||
Reference in New Issue
Block a user