mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-16 02:38:02 +00:00
Merge branch 'gain_class_level' into 'master'
Implement Class mechanism See merge request core-developers/forge!4955
This commit is contained in:
@@ -50,6 +50,7 @@ public enum SpellApiToAi {
|
||||
.put(ApiType.ChooseSource, ChooseSourceAi.class)
|
||||
.put(ApiType.ChooseType, ChooseTypeAi.class)
|
||||
.put(ApiType.Clash, ClashAi.class)
|
||||
.put(ApiType.ClassLevelUp, AlwaysPlayAi.class)
|
||||
.put(ApiType.Cleanup, AlwaysPlayAi.class)
|
||||
.put(ApiType.Clone, CloneAi.class)
|
||||
.put(ApiType.CopyPermanent, CopyPermanentAi.class)
|
||||
|
||||
@@ -148,6 +148,18 @@ public abstract class CardTraitBase extends GameObject implements IHasCardView,
|
||||
return getParamOrDefault("Secondary", "False").equals("True");
|
||||
}
|
||||
|
||||
|
||||
public final boolean isClassAbility() {
|
||||
return hasParam("ClassLevel");
|
||||
}
|
||||
public final boolean isClassLevelNAbility(int level) {
|
||||
String classLevel = getParamOrDefault("ClassLevel", "0");
|
||||
if (!StringUtils.isNumeric(classLevel)) {
|
||||
classLevel = classLevel.substring(2);
|
||||
}
|
||||
return level == Integer.parseInt(classLevel);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* matchesValid.
|
||||
@@ -460,6 +472,15 @@ public abstract class CardTraitBase extends GameObject implements IHasCardView,
|
||||
final Player active = game.getPhaseHandler().getPlayerTurn();
|
||||
return !active.getActivateLoyaltyAbilityThisTurn();
|
||||
}
|
||||
|
||||
if (params.containsKey("ClassLevel")) {
|
||||
final int level = getHostCard().getClassLevel();
|
||||
final int levelMin = Integer.parseInt(params.get("ClassLevel"));
|
||||
if (level < levelMin) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import forge.card.ColorSet;
|
||||
import forge.card.MagicColor;
|
||||
import forge.card.mana.ManaAtom;
|
||||
import forge.game.ability.AbilityUtils;
|
||||
import forge.game.ability.ApiType;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.card.CardState;
|
||||
import forge.game.cost.Cost;
|
||||
@@ -166,6 +167,8 @@ public class ForgeScript {
|
||||
return sa.isForetelling();
|
||||
} else if (property.equals("Foretold")) {
|
||||
return sa.isForetold();
|
||||
} else if (property.equals("ClassLevelUp")) {
|
||||
return sa.getApi() == ApiType.ClassLevelUp;
|
||||
} else if (property.equals("MayPlaySource")) {
|
||||
StaticAbility m = sa.getMayPlay();
|
||||
if (m == null) {
|
||||
|
||||
@@ -33,6 +33,7 @@ public enum AbilityKey {
|
||||
Cause("Cause"),
|
||||
Causer("Causer"),
|
||||
Championed("Championed"),
|
||||
ClassLevel("ClassLevel"),
|
||||
Cost("Cost"),
|
||||
CostStack("CostStack"),
|
||||
CounterAmount("CounterAmount"),
|
||||
|
||||
@@ -47,6 +47,7 @@ public enum ApiType {
|
||||
ChooseSource (ChooseSourceEffect.class),
|
||||
ChooseType (ChooseTypeEffect.class),
|
||||
Clash (ClashEffect.class),
|
||||
ClassLevelUp (ClassLevelUpEffect.class),
|
||||
Cleanup (CleanUpEffect.class),
|
||||
Clone (CloneEffect.class),
|
||||
CompanionChoose (ChooseCompanionEffect.class),
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
package forge.game.ability.effects;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import forge.game.Game;
|
||||
import forge.game.ability.AbilityKey;
|
||||
import forge.game.ability.SpellAbilityEffect;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.game.trigger.TriggerType;
|
||||
|
||||
public class ClassLevelUpEffect extends SpellAbilityEffect {
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.card.abilityfactory.SpellEffect#resolve(java.util.Map, forge.card.spellability.SpellAbility)
|
||||
*/
|
||||
@Override
|
||||
public void resolve(SpellAbility sa) {
|
||||
final Card host = sa.getHostCard();
|
||||
final Game game = host.getGame();
|
||||
final int level = host.getClassLevel() + 1;
|
||||
host.setClassLevel(level);
|
||||
|
||||
// Run ClassLevelGained trigger
|
||||
final Map<AbilityKey, Object> runParams = AbilityKey.mapFromCard(host);
|
||||
runParams.put(AbilityKey.ClassLevel, level);
|
||||
game.getTriggerHandler().runTrigger(TriggerType.ClassLevelGained, runParams, false);
|
||||
}
|
||||
}
|
||||
@@ -240,6 +240,8 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
||||
private boolean foretoldThisTurn = false;
|
||||
private boolean foretoldByEffect = false;
|
||||
|
||||
private int classLevel = 1;
|
||||
|
||||
private long bestowTimestamp = -1;
|
||||
private long transformedTimestamp = 0;
|
||||
private long mutatedTimestamp = -1;
|
||||
@@ -389,6 +391,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
||||
view.updateChangedColorWords(this);
|
||||
view.updateChangedTypes(this);
|
||||
view.updateSickness(this);
|
||||
view.updateClassLevel(this);
|
||||
}
|
||||
|
||||
public boolean changeToState(final CardStateName state) {
|
||||
@@ -2158,6 +2161,8 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
||||
String desc = "(As this Saga enters and after your draw step, "
|
||||
+ " add a lore counter. Sacrifice after " + Strings.repeat("I", Integer.valueOf(k[1])) + ".)";
|
||||
sbLong.append(desc);
|
||||
} else if (keyword.startsWith("Class")) {
|
||||
sbLong.append("(Gain the next level as a sorcery to add its ability.)");
|
||||
}
|
||||
else {
|
||||
if ((i != 0) && (sb.length() != 0)) {
|
||||
@@ -2247,7 +2252,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
||||
// here. The rest will be printed later.
|
||||
StringBuilder replacementEffects = new StringBuilder();
|
||||
for (final ReplacementEffect replacementEffect : state.getReplacementEffects()) {
|
||||
if (!replacementEffect.isSecondary()) {
|
||||
if (!replacementEffect.isSecondary() && !replacementEffect.isClassAbility()) {
|
||||
String text = replacementEffect.getDescription();
|
||||
// Get original description since text might be translated
|
||||
if (replacementEffect.hasParam("Description") &&
|
||||
@@ -2292,7 +2297,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
||||
|
||||
// Triggered abilities
|
||||
for (final Trigger trig : state.getTriggers()) {
|
||||
if (!trig.isSecondary()) {
|
||||
if (!trig.isSecondary() && !trig.isClassAbility()) {
|
||||
String trigStr = trig.replaceAbilityText(trig.toString(), state);
|
||||
sb.append(trigStr.replaceAll("\\\\r\\\\n", "\r\n")).append("\r\n");
|
||||
}
|
||||
@@ -2303,7 +2308,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
||||
|
||||
// static abilities
|
||||
for (final StaticAbility stAb : state.getStaticAbilities()) {
|
||||
if (!stAb.isSecondary()) {
|
||||
if (!stAb.isSecondary() && !stAb.isClassAbility()) {
|
||||
final String stAbD = stAb.toString();
|
||||
if (!stAbD.equals("")) {
|
||||
sb.append(stAbD).append("\r\n");
|
||||
@@ -2315,7 +2320,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
||||
|
||||
for (final SpellAbility sa : state.getSpellAbilities()) {
|
||||
// This code block is not shared by instants or sorceries. We don't need to check for permanence.
|
||||
if (sa == null || sa.isSecondary()) {
|
||||
if (sa == null || sa.isSecondary() || sa.isClassAbility()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -2385,6 +2390,48 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
||||
}
|
||||
}
|
||||
|
||||
// Class Abilities
|
||||
if (isClassCard()) {
|
||||
String linebreak = "\r\n\r\n";
|
||||
sb.append(linebreak);
|
||||
// Currently the maximum levels of all Class cards are all 3
|
||||
for (int level = 1; level <= 3; ++level) {
|
||||
boolean disabled = level > getClassLevel() && isInZone(ZoneType.Battlefield);
|
||||
final String grayTag = "<span style=\"color:gray;\">";
|
||||
final String endTag = "</span>";
|
||||
for (final Trigger trig : state.getTriggers()) {
|
||||
if (trig.isClassLevelNAbility(level) && !trig.isSecondary()) {
|
||||
if (disabled) sb.append(grayTag);
|
||||
sb.append(trig.toString());
|
||||
if (disabled) sb.append(endTag);
|
||||
sb.append(linebreak);
|
||||
}
|
||||
}
|
||||
for (final ReplacementEffect re : state.getReplacementEffects()) {
|
||||
if (re.isClassLevelNAbility(level) && !re.isSecondary()) {
|
||||
if (disabled) sb.append(grayTag);
|
||||
sb.append(re.getDescription());
|
||||
if (disabled) sb.append(endTag);
|
||||
sb.append(linebreak);
|
||||
}
|
||||
}
|
||||
for (final StaticAbility st : state.getStaticAbilities()) {
|
||||
if (st.isClassLevelNAbility(level) && !st.isSecondary()) {
|
||||
if (disabled) sb.append(grayTag);
|
||||
sb.append(st.toString());
|
||||
if (disabled) sb.append(endTag);
|
||||
sb.append(linebreak);
|
||||
}
|
||||
}
|
||||
// Currently all activated abilities on Class cards are level up abilities
|
||||
for (final SpellAbility sa : state.getSpellAbilities()) {
|
||||
if (sa.isClassLevelNAbility(level) && !sa.isSecondary()) {
|
||||
sb.append(sa.toString()).append(linebreak);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE:
|
||||
if (sb.toString().contains(" (NOTE: ")) {
|
||||
sb.insert(sb.indexOf("(NOTE: "), "\r\n");
|
||||
@@ -5474,6 +5521,18 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
||||
foretoldThisTurn = false;
|
||||
}
|
||||
|
||||
public final int getClassLevel() {
|
||||
return classLevel;
|
||||
}
|
||||
public void setClassLevel(int level) {
|
||||
classLevel = level;
|
||||
view.updateClassLevel(this);
|
||||
view.getCurrentState().updateAbilityText(this, getCurrentState());
|
||||
}
|
||||
public boolean isClassCard() {
|
||||
return getType().hasStringType("Class");
|
||||
}
|
||||
|
||||
public final void animateBestow() {
|
||||
animateBestow(true);
|
||||
}
|
||||
|
||||
@@ -2556,6 +2556,25 @@ public class CardFactoryUtil {
|
||||
sa.setAlternativeCost(AlternativeCost.Bestow);
|
||||
sa.setIntrinsic(intrinsic);
|
||||
inst.addSpellAbility(sa);
|
||||
} else if (keyword.startsWith("Class")) {
|
||||
final String[] k = keyword.split(":");
|
||||
final String[] costs = k[2].split(",");
|
||||
if (costs.length != Integer.valueOf(k[1]) - 1) {
|
||||
throw new RuntimeException("Class max differ from cost amount");
|
||||
}
|
||||
|
||||
for (int i = 0; i < costs.length; ++i) {
|
||||
final String cost = costs[i];
|
||||
final StringBuilder sbClass = new StringBuilder();
|
||||
sbClass.append("AB$ ClassLevelUp | Cost$ ").append(cost);
|
||||
sbClass.append(" | ClassLevel$ EQ").append(i + 1);
|
||||
sbClass.append(" | SorcerySpeed$ True");
|
||||
sbClass.append(" | StackDescription$ SpellDescription | SpellDescription$ Level ").append(i + 2);
|
||||
|
||||
final SpellAbility sa = AbilityFactory.getAbility(sbClass.toString(), card);
|
||||
sa.setIntrinsic(intrinsic);
|
||||
inst.addSpellAbility(sa);
|
||||
}
|
||||
} else if (keyword.startsWith("Dash")) {
|
||||
final String[] k = keyword.split(":");
|
||||
final Cost dashCost = new Cost(k[1], false);
|
||||
|
||||
@@ -396,6 +396,13 @@ public class CardView extends GameEntityView {
|
||||
set(TrackableProperty.CurrentRoom, c.getCurrentRoom());
|
||||
}
|
||||
|
||||
public int getClassLevel() {
|
||||
return get(TrackableProperty.ClassLevel);
|
||||
}
|
||||
void updateClassLevel(Card c) {
|
||||
set(TrackableProperty.ClassLevel, c.getClassLevel());
|
||||
}
|
||||
|
||||
private String getRemembered() {
|
||||
return get(TrackableProperty.Remembered);
|
||||
}
|
||||
|
||||
@@ -182,6 +182,11 @@ public class SpellAbilityRestriction extends SpellAbilityVariables {
|
||||
this.setSvarOperator(params.get("SVarCompare").substring(0, 2));
|
||||
this.setSvarOperand(params.get("SVarCompare").substring(2));
|
||||
}
|
||||
|
||||
if (params.containsKey("ClassLevel")) {
|
||||
this.setClassLevelOperator(params.get("ClassLevel").substring(0, 2));
|
||||
this.setClassLevel(params.get("ClassLevel").substring(2));
|
||||
}
|
||||
} // end setRestrictions()
|
||||
|
||||
/**
|
||||
@@ -525,6 +530,15 @@ public class SpellAbilityRestriction extends SpellAbilityVariables {
|
||||
}
|
||||
}
|
||||
|
||||
if (this.getClassLevel() != null) {
|
||||
final int level = c.getClassLevel();
|
||||
final int levelOperand = AbilityUtils.calculateAmount(c, this.getClassLevel(), sa);
|
||||
|
||||
if (!Expressions.compare(level, this.getClassLevelOperator(), levelOperand)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,12 +6,12 @@
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
@@ -30,7 +30,7 @@ import forge.game.zone.ZoneType;
|
||||
* <p>
|
||||
* SpellAbilityVariables class.
|
||||
* </p>
|
||||
*
|
||||
*
|
||||
* @author Forge
|
||||
* @version $Id$
|
||||
* @since 1.0.15
|
||||
@@ -51,7 +51,7 @@ public class SpellAbilityVariables implements Cloneable {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param sav
|
||||
* SpellAbilityVariables
|
||||
*/
|
||||
@@ -93,6 +93,8 @@ public class SpellAbilityVariables implements Cloneable {
|
||||
this.targetValidTargeting = sav.getTargetValidTargeting();
|
||||
this.targetsSingleTarget = sav.targetsSingleTarget();
|
||||
this.presenceCondition = sav.getPresenceCondition();
|
||||
this.classLevel = sav.getClassLevel();
|
||||
this.classLevelOperator = sav.getClassLevelOperator();
|
||||
}
|
||||
|
||||
// default values for Sorcery speed abilities
|
||||
@@ -193,7 +195,7 @@ public class SpellAbilityVariables implements Cloneable {
|
||||
|
||||
/** The chosen colors string. */
|
||||
private String chosenColors = null;
|
||||
|
||||
|
||||
/** The target valid targeting */
|
||||
private String targetValidTargeting = null;
|
||||
|
||||
@@ -203,11 +205,15 @@ public class SpellAbilityVariables implements Cloneable {
|
||||
/** The Presence keyword value containing the relevant condition */
|
||||
private String presenceCondition = "";
|
||||
|
||||
/** The class level. */
|
||||
private String classLevel = null;
|
||||
private String classLevelOperator = "EQ";
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Setter for the field <code>manaSpent</code>.
|
||||
* </p>
|
||||
*
|
||||
*
|
||||
* @param s
|
||||
* a {@link java.lang.String} object.
|
||||
*/
|
||||
@@ -219,7 +225,7 @@ public class SpellAbilityVariables implements Cloneable {
|
||||
* <p>
|
||||
* Getter for the field <code>manaSpent</code>.
|
||||
* </p>
|
||||
*
|
||||
*
|
||||
* @return a {@link java.lang.String} object.
|
||||
*/
|
||||
public final String getManaSpent() {
|
||||
@@ -237,7 +243,7 @@ public class SpellAbilityVariables implements Cloneable {
|
||||
* <p>
|
||||
* Setter for the field <code>zone</code>.
|
||||
* </p>
|
||||
*
|
||||
*
|
||||
* @param zone
|
||||
* a {@link java.lang.String} object.
|
||||
*/
|
||||
@@ -249,7 +255,7 @@ public class SpellAbilityVariables implements Cloneable {
|
||||
* <p>
|
||||
* Getter for the field <code>zone</code>.
|
||||
* </p>
|
||||
*
|
||||
*
|
||||
* @return a {@link java.lang.String} object.
|
||||
*/
|
||||
public final ZoneType getZone() {
|
||||
@@ -284,7 +290,7 @@ public class SpellAbilityVariables implements Cloneable {
|
||||
* <p>
|
||||
* setPlayerTurn.
|
||||
* </p>
|
||||
*
|
||||
*
|
||||
* @param bTurn
|
||||
* a boolean.
|
||||
*/
|
||||
@@ -296,7 +302,7 @@ public class SpellAbilityVariables implements Cloneable {
|
||||
* <p>
|
||||
* getPlayerTurn.
|
||||
* </p>
|
||||
*
|
||||
*
|
||||
* @return a boolean.
|
||||
*/
|
||||
public final boolean getPlayerTurn() {
|
||||
@@ -307,7 +313,7 @@ public class SpellAbilityVariables implements Cloneable {
|
||||
* <p>
|
||||
* setOpponentTurn.
|
||||
* </p>
|
||||
*
|
||||
*
|
||||
* @param bTurn
|
||||
* a boolean.
|
||||
*/
|
||||
@@ -319,7 +325,7 @@ public class SpellAbilityVariables implements Cloneable {
|
||||
* <p>
|
||||
* getOpponentTurn.
|
||||
* </p>
|
||||
*
|
||||
*
|
||||
* @return a boolean.
|
||||
*/
|
||||
public final boolean getOpponentTurn() {
|
||||
@@ -330,7 +336,7 @@ public class SpellAbilityVariables implements Cloneable {
|
||||
* <p>
|
||||
* Setter for the field <code>activationLimit</code>.
|
||||
* </p>
|
||||
*
|
||||
*
|
||||
* @param limit
|
||||
* a int.
|
||||
*/
|
||||
@@ -342,7 +348,7 @@ public class SpellAbilityVariables implements Cloneable {
|
||||
* <p>
|
||||
* Setter for the field <code>gameActivationLimit</code>.
|
||||
* </p>
|
||||
*
|
||||
*
|
||||
* @param limit
|
||||
* a int.
|
||||
*/
|
||||
@@ -354,7 +360,7 @@ public class SpellAbilityVariables implements Cloneable {
|
||||
* <p>
|
||||
* Setter for the field <code>phases</code>.
|
||||
* </p>
|
||||
*
|
||||
*
|
||||
* @param phases
|
||||
* a {@link java.lang.String} object.
|
||||
*/
|
||||
@@ -378,7 +384,7 @@ public class SpellAbilityVariables implements Cloneable {
|
||||
* <p>
|
||||
* setActivateCardsInHand.
|
||||
* </p>
|
||||
*
|
||||
*
|
||||
* @param cards
|
||||
* a int.
|
||||
*/
|
||||
@@ -405,7 +411,7 @@ public class SpellAbilityVariables implements Cloneable {
|
||||
public void setRevolt(final boolean bRevolt) { revolt = bRevolt; }
|
||||
|
||||
public void setDesert(final boolean bDesert) { desert = bDesert; }
|
||||
|
||||
|
||||
public void setBlessing(final boolean bBlessing) { blessing = bBlessing; }
|
||||
|
||||
/** Optional Costs */
|
||||
@@ -438,7 +444,7 @@ public class SpellAbilityVariables implements Cloneable {
|
||||
* <p>
|
||||
* setIsPresent.
|
||||
* </p>
|
||||
*
|
||||
*
|
||||
* @param present
|
||||
* a {@link java.lang.String} object.
|
||||
*/
|
||||
@@ -450,7 +456,7 @@ public class SpellAbilityVariables implements Cloneable {
|
||||
* <p>
|
||||
* Setter for the field <code>presentCompare</code>.
|
||||
* </p>
|
||||
*
|
||||
*
|
||||
* @param compare
|
||||
* a {@link java.lang.String} object.
|
||||
*/
|
||||
@@ -460,7 +466,7 @@ public class SpellAbilityVariables implements Cloneable {
|
||||
|
||||
/**
|
||||
* Gets the present zone.
|
||||
*
|
||||
*
|
||||
* @return the present zone
|
||||
*/
|
||||
public final ZoneType getPresentZone() {
|
||||
@@ -469,7 +475,7 @@ public class SpellAbilityVariables implements Cloneable {
|
||||
|
||||
/**
|
||||
* Sets the present zone.
|
||||
*
|
||||
*
|
||||
* @param presentZone
|
||||
* the new present zone
|
||||
*/
|
||||
@@ -481,7 +487,7 @@ public class SpellAbilityVariables implements Cloneable {
|
||||
* <p>
|
||||
* Setter for the field <code>presentDefined</code>.
|
||||
* </p>
|
||||
*
|
||||
*
|
||||
* @param defined
|
||||
* a {@link java.lang.String} object.
|
||||
*/
|
||||
@@ -494,7 +500,7 @@ public class SpellAbilityVariables implements Cloneable {
|
||||
* <p>
|
||||
* Setter for the field <code>svarToCheck</code>.
|
||||
* </p>
|
||||
*
|
||||
*
|
||||
* @param sVar
|
||||
* a {@link java.lang.String} object.
|
||||
*/
|
||||
@@ -509,7 +515,7 @@ public class SpellAbilityVariables implements Cloneable {
|
||||
* <p>
|
||||
* Setter for the field <code>svarOperator</code>.
|
||||
* </p>
|
||||
*
|
||||
*
|
||||
* @param operator
|
||||
* a {@link java.lang.String} object.
|
||||
*/
|
||||
@@ -521,7 +527,7 @@ public class SpellAbilityVariables implements Cloneable {
|
||||
* <p>
|
||||
* Setter for the field <code>svarOperand</code>.
|
||||
* </p>
|
||||
*
|
||||
*
|
||||
* @param operand
|
||||
* a {@link java.lang.String} object.
|
||||
*/
|
||||
@@ -539,7 +545,7 @@ public class SpellAbilityVariables implements Cloneable {
|
||||
|
||||
/**
|
||||
* Gets the activation limit.
|
||||
*
|
||||
*
|
||||
* @return the activationLimit
|
||||
*/
|
||||
public final int getActivationLimit() {
|
||||
@@ -548,7 +554,7 @@ public class SpellAbilityVariables implements Cloneable {
|
||||
|
||||
/**
|
||||
* Gets the activation limit.
|
||||
*
|
||||
*
|
||||
* @return the activationLimit
|
||||
*/
|
||||
public final int getGameActivationLimit() {
|
||||
@@ -559,7 +565,7 @@ public class SpellAbilityVariables implements Cloneable {
|
||||
* <p>
|
||||
* Setter for the field <code>limitToCheck</code>.
|
||||
* </p>
|
||||
*
|
||||
*
|
||||
* @param limit
|
||||
* a {@link java.lang.String} object.
|
||||
*/
|
||||
@@ -571,7 +577,7 @@ public class SpellAbilityVariables implements Cloneable {
|
||||
* <p>
|
||||
* Setter for the field <code>GamelimitToCheck</code>.
|
||||
* </p>
|
||||
*
|
||||
*
|
||||
* @param limit
|
||||
* a {@link java.lang.String} object.
|
||||
*/
|
||||
@@ -583,7 +589,7 @@ public class SpellAbilityVariables implements Cloneable {
|
||||
* <p>
|
||||
* Getter for the field <code>limitToCheck</code>.
|
||||
* </p>
|
||||
*
|
||||
*
|
||||
* @return the limitToCheck
|
||||
* a {@link java.lang.String} object.
|
||||
*/
|
||||
@@ -595,7 +601,7 @@ public class SpellAbilityVariables implements Cloneable {
|
||||
* <p>
|
||||
* Getter for the field <code>getGameLimitToCheck</code>.
|
||||
* </p>
|
||||
*
|
||||
*
|
||||
* @return the getGameLimitToCheck
|
||||
* a {@link java.lang.String} object.
|
||||
*/
|
||||
@@ -610,7 +616,7 @@ public class SpellAbilityVariables implements Cloneable {
|
||||
public final boolean isDelirium() { return this.delirium; }
|
||||
|
||||
public final boolean isHellbent() { return this.hellbent; }
|
||||
|
||||
|
||||
public final boolean isRevolt() { return this.revolt; }
|
||||
|
||||
public final boolean isDesert() { return this.desert; }
|
||||
@@ -626,7 +632,7 @@ public class SpellAbilityVariables implements Cloneable {
|
||||
|
||||
/**
|
||||
* Checks if is player turn.
|
||||
*
|
||||
*
|
||||
* @return the playerTurn
|
||||
*/
|
||||
public final boolean isPlayerTurn() {
|
||||
@@ -635,7 +641,7 @@ public class SpellAbilityVariables implements Cloneable {
|
||||
|
||||
/**
|
||||
* Gets the present compare.
|
||||
*
|
||||
*
|
||||
* @return the presentCompare
|
||||
*/
|
||||
public final String getPresentCompare() {
|
||||
@@ -644,7 +650,7 @@ public class SpellAbilityVariables implements Cloneable {
|
||||
|
||||
/**
|
||||
* Gets the life total.
|
||||
*
|
||||
*
|
||||
* @return the lifeTotal
|
||||
*/
|
||||
public final String getLifeTotal() {
|
||||
@@ -653,7 +659,7 @@ public class SpellAbilityVariables implements Cloneable {
|
||||
|
||||
/**
|
||||
* Sets the life total.
|
||||
*
|
||||
*
|
||||
* @param lifeTotal0
|
||||
* the lifeTotal to set
|
||||
*/
|
||||
@@ -663,7 +669,7 @@ public class SpellAbilityVariables implements Cloneable {
|
||||
|
||||
/**
|
||||
* Gets the life amount.
|
||||
*
|
||||
*
|
||||
* @return the lifeAmount
|
||||
*/
|
||||
public final String getLifeAmount() {
|
||||
@@ -672,7 +678,7 @@ public class SpellAbilityVariables implements Cloneable {
|
||||
|
||||
/**
|
||||
* Sets the life amount.
|
||||
*
|
||||
*
|
||||
* @param lifeAmount0
|
||||
* the lifeAmount to set
|
||||
*/
|
||||
@@ -682,7 +688,7 @@ public class SpellAbilityVariables implements Cloneable {
|
||||
|
||||
/**
|
||||
* Gets the phases.
|
||||
*
|
||||
*
|
||||
* @return the phases
|
||||
*/
|
||||
public final Set<PhaseType> getPhases() {
|
||||
@@ -701,7 +707,7 @@ public class SpellAbilityVariables implements Cloneable {
|
||||
|
||||
/**
|
||||
* Gets the present defined.
|
||||
*
|
||||
*
|
||||
* @return the presentDefined
|
||||
*/
|
||||
public final String getPresentDefined() {
|
||||
@@ -710,7 +716,7 @@ public class SpellAbilityVariables implements Cloneable {
|
||||
|
||||
/**
|
||||
* Set the player defined.
|
||||
*
|
||||
*
|
||||
*/
|
||||
public final void setPlayerDefined(final String b) {
|
||||
this.playerDefined = b;
|
||||
@@ -718,7 +724,7 @@ public class SpellAbilityVariables implements Cloneable {
|
||||
|
||||
/**
|
||||
* Gets the player defined.
|
||||
*
|
||||
*
|
||||
* @return the playerDefined
|
||||
*/
|
||||
public final String getPlayerDefined() {
|
||||
@@ -727,7 +733,7 @@ public class SpellAbilityVariables implements Cloneable {
|
||||
|
||||
/**
|
||||
* Gets the player contains.
|
||||
*
|
||||
*
|
||||
* @return the playerContains
|
||||
*/
|
||||
public final String getPlayerContains() {
|
||||
@@ -736,7 +742,7 @@ public class SpellAbilityVariables implements Cloneable {
|
||||
|
||||
/**
|
||||
* Set the player contains.
|
||||
*
|
||||
*
|
||||
*/
|
||||
public final void setPlayerContains(final String contains) {
|
||||
this.playerContains = contains;
|
||||
@@ -744,7 +750,7 @@ public class SpellAbilityVariables implements Cloneable {
|
||||
|
||||
/**
|
||||
* Gets the s var operand.
|
||||
*
|
||||
*
|
||||
* @return the sVarOperand
|
||||
*/
|
||||
public final String getsVarOperand() {
|
||||
@@ -756,7 +762,7 @@ public class SpellAbilityVariables implements Cloneable {
|
||||
|
||||
/**
|
||||
* Sets the s var operand.
|
||||
*
|
||||
*
|
||||
* @param sVarOperand0
|
||||
* the sVarOperand to set
|
||||
*/
|
||||
@@ -769,7 +775,7 @@ public class SpellAbilityVariables implements Cloneable {
|
||||
|
||||
/**
|
||||
* Gets the s var to check.
|
||||
*
|
||||
*
|
||||
* @return the sVarToCheck
|
||||
*/
|
||||
public final String getsVarToCheck() {
|
||||
@@ -781,7 +787,7 @@ public class SpellAbilityVariables implements Cloneable {
|
||||
|
||||
/**
|
||||
* Sets the s var to check.
|
||||
*
|
||||
*
|
||||
* @param sVarToCheck
|
||||
* the sVarToCheck to set
|
||||
*/
|
||||
@@ -794,7 +800,7 @@ public class SpellAbilityVariables implements Cloneable {
|
||||
|
||||
/**
|
||||
* Gets the s var operator.
|
||||
*
|
||||
*
|
||||
* @return the sVarOperator
|
||||
*/
|
||||
public final String getsVarOperator() {
|
||||
@@ -806,7 +812,7 @@ public class SpellAbilityVariables implements Cloneable {
|
||||
|
||||
/**
|
||||
* Sets the s var operator.
|
||||
*
|
||||
*
|
||||
* @param sVarOperator0
|
||||
* the sVarOperator to set
|
||||
*/
|
||||
@@ -819,7 +825,7 @@ public class SpellAbilityVariables implements Cloneable {
|
||||
|
||||
/**
|
||||
* Checks if is opponent turn.
|
||||
*
|
||||
*
|
||||
* @return the opponentTurn
|
||||
*/
|
||||
public final boolean isOpponentTurn() {
|
||||
@@ -828,7 +834,7 @@ public class SpellAbilityVariables implements Cloneable {
|
||||
|
||||
/**
|
||||
* Gets the cards in hand.
|
||||
*
|
||||
*
|
||||
* @return the cardsInHand
|
||||
*/
|
||||
public final int getCardsInHand() {
|
||||
@@ -840,7 +846,7 @@ public class SpellAbilityVariables implements Cloneable {
|
||||
|
||||
/**
|
||||
* Sets the cards in hand.
|
||||
*
|
||||
*
|
||||
* @param cardsInHand0
|
||||
* the cardsInHand to set
|
||||
*/
|
||||
@@ -853,7 +859,7 @@ public class SpellAbilityVariables implements Cloneable {
|
||||
|
||||
/**
|
||||
* Gets the checks if is present.
|
||||
*
|
||||
*
|
||||
* @return the isPresent
|
||||
*/
|
||||
public final String getIsPresent() {
|
||||
@@ -868,7 +874,7 @@ public class SpellAbilityVariables implements Cloneable {
|
||||
* <p>
|
||||
* Getter for the field <code>ColorToCheck</code>.
|
||||
* </p>
|
||||
*
|
||||
*
|
||||
* @return the String, chosenColors.
|
||||
*/
|
||||
public final String getColorToCheck() {
|
||||
@@ -888,14 +894,14 @@ public class SpellAbilityVariables implements Cloneable {
|
||||
public void setTargetValidTargeting(String targetValidTargeting) {
|
||||
this.targetValidTargeting = targetValidTargeting;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return the targetsSingleTarget
|
||||
*/
|
||||
public boolean targetsSingleTarget() {
|
||||
return targetsSingleTarget;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param b the targetsSingleTarget to set
|
||||
*/
|
||||
@@ -925,4 +931,18 @@ public class SpellAbilityVariables implements Cloneable {
|
||||
public void setPresenceCondition(String s) {
|
||||
this.presenceCondition = s;
|
||||
}
|
||||
|
||||
public String getClassLevel() {
|
||||
return classLevel;
|
||||
}
|
||||
public void setClassLevel(String level) {
|
||||
classLevel = level;
|
||||
}
|
||||
|
||||
public String getClassLevelOperator() {
|
||||
return classLevelOperator;
|
||||
}
|
||||
public void setClassLevelOperator(String op) {
|
||||
classLevelOperator = op;
|
||||
}
|
||||
} // end class SpellAbilityVariables
|
||||
|
||||
@@ -585,6 +585,14 @@ public class StaticAbility extends CardTraitBase implements IIdentifiable, Clone
|
||||
}
|
||||
}
|
||||
|
||||
if (hasParam("ClassLevel")) {
|
||||
final int level = this.hostCard.getClassLevel();
|
||||
final int levelMin = Integer.parseInt(getParam("ClassLevel"));
|
||||
if (level < levelMin) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (hasParam("CheckSVar")) {
|
||||
final int sVar = AbilityUtils.calculateAmount(this.hostCard, getParam("CheckSVar"), this);
|
||||
String comparator = "GE1";
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
package forge.game.trigger;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import forge.game.ability.AbilityKey;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
|
||||
public class TriggerClassLevelGained extends Trigger {
|
||||
|
||||
public TriggerClassLevelGained(final Map<String, String> params, final Card host, final boolean intrinsic) {
|
||||
super(params, host, intrinsic);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean performTest(final Map<AbilityKey, Object> runParams) {
|
||||
if (!matchesValidParam("ValidCard", runParams.get(AbilityKey.Card))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (hasParam("ClassLevel") && runParams.containsKey(AbilityKey.ClassLevel)) {
|
||||
final int levelCondition = Integer.parseInt(getParam("ClassLevel"));
|
||||
final int level = (Integer) runParams.get(AbilityKey.ClassLevel);
|
||||
|
||||
if (levelCondition != level) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setTriggeringObjects(final SpellAbility sa, Map<AbilityKey, Object> runParams) {
|
||||
sa.setTriggeringObjectsFrom(runParams, AbilityKey.ClassLevel);
|
||||
}
|
||||
|
||||
public String getImportantStackObjects(SpellAbility sa) {
|
||||
Integer level = (Integer)sa.getTriggeringObject(AbilityKey.ClassLevel);
|
||||
StringBuilder sb = new StringBuilder("Class Level: ");
|
||||
sb.append(level);
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
@@ -38,6 +38,7 @@ public enum TriggerType {
|
||||
ChangesZone(TriggerChangesZone.class),
|
||||
ChangesZoneAll(TriggerChangesZoneAll.class),
|
||||
Clashed(TriggerClashed.class),
|
||||
ClassLevelGained(TriggerClassLevelGained.class),
|
||||
CounterAdded(TriggerCounterAdded.class),
|
||||
CounterAddedOnce(TriggerCounterAddedOnce.class),
|
||||
CounterPlayerAddedAll(TriggerCounterPlayerAddedAll.class),
|
||||
|
||||
@@ -63,6 +63,7 @@ public enum TrackableProperty {
|
||||
ChosenDirection(TrackableTypes.EnumType(Direction.class)),
|
||||
ChosenEvenOdd(TrackableTypes.EnumType(EvenOdd.class)),
|
||||
ChosenMode(TrackableTypes.StringType),
|
||||
ClassLevel(TrackableTypes.IntegerType),
|
||||
CurrentRoom(TrackableTypes.StringType),
|
||||
Remembered(TrackableTypes.StringType),
|
||||
NamedCard(TrackableTypes.StringType),
|
||||
|
||||
10
forge-gui/res/cardsfolder/upcoming/barbarian_class.txt
Normal file
10
forge-gui/res/cardsfolder/upcoming/barbarian_class.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
Name:Barbarian Class
|
||||
ManaCost:R
|
||||
Types:Enchantment Class
|
||||
K:Class:3:1 R,2 R
|
||||
S:Mode$ Continuous | ClassLevel$ 1 | Affected$ You | AddKeyword$ If you would roll one or more dice, instead roll that many dice plus one and ignore the lowest roll. | Description$ If you would roll one or more dice, instead roll that many dice plus one and ignore the lowest roll.
|
||||
T:Mode$ RolledDieOnce | ClassLevel$ 2 | TriggerZones$ Battlefield | ValidPlayer$ You | Execute$ TrigPump | TriggerDescription$ Whenever you roll one or more dice, target creature you control gets +2/+0 and gains menace until end of turn.
|
||||
SVar:TrigPump:DB$ Pump | ValidTgts$ Creature.YouCtrl | NumAtt$ 2 | KW$ Menace
|
||||
S:Mode$ Continuous | ClassLevel$ 3 | EffectZone$ Battlefield | Affected$ Creature.YouCtrl | AddKeyword$ Haste | Description$ Creatures you control have haste.
|
||||
SVar:PlayMain1:TRUE
|
||||
Oracle:(Gain the next level as a sorcery to add its ability.)\nIf you would roll one or more dice, instead roll that many dice plus one and ignore the lowest roll.\n{1}{R}: Level 2\nWhenever you roll one or more dice, target creature you control gets +2/+0 and gains menace until end of turn.\n{2}{R}: Level 3\nCreatures you control have haste.
|
||||
14
forge-gui/res/cardsfolder/upcoming/bard_class.txt
Normal file
14
forge-gui/res/cardsfolder/upcoming/bard_class.txt
Normal file
@@ -0,0 +1,14 @@
|
||||
Name:Bard Class
|
||||
ManaCost:R G
|
||||
Types:Enchantment Class
|
||||
K:Class:3:R G,3 R G
|
||||
R:Event$ Moved | ClassLevel$ 1 | ActiveZones$ Battlefield | ValidCard$ Creature.Legendary+YouCtrl | ReplaceWith$ EtbAddCounter | Destination$ Battlefield | Description$ Legendary creatures you control enter the battlefield with an additional +1/+1 counter on them.
|
||||
SVar:EtbAddCounter:DB$ PutCounter | ETB$ True | Defined$ ReplacedCard | CounterType$ P1P1 | CounterNum$ 1 | SubAbility$ ToBattlefield
|
||||
SVar:ToBattlefield:DB$ InternalEtbReplacement
|
||||
S:Mode$ ReduceCost | ClassLevel$ 2 | ValidCard$ Legendary | Type$ Spell | Activator$ You | Amount$ 1 | Color$ R G | Description$ Legendary spells you cast cost {R}{G} less to cast. This effect reduces only the amount of colored mana you pay.
|
||||
T:Mode$ SpellCast | ClassLevel$ 3 | ValidCard$ Legendary | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigImpulsiveDraw | TriggerDescription$ Whenever you cast a legendary spell, exile the top two cards of your library. You may play them this turn.
|
||||
SVar:TrigImpulsiveDraw:DB$ Dig | Defined$ TriggeredPlayer | DigNum$ 2 | ChangeNum$ All | DestinationZone$ Exile | RememberChanged$ True | SubAbility$ DBEffect
|
||||
SVar:DBEffect:DB$ Effect | EffectOwner$ TriggeredPlayer | RememberObjects$ RememberedCard | StaticAbilities$ StPlay | SubAbility$ DBCleanup | ForgetOnMoved$ Exile
|
||||
SVar:StPlay:Mode$ Continuous | MayPlay$ True | EffectZone$ Command | Affected$ Card.IsRemembered | AffectedZone$ Exile | Description$ You may play them this turn.
|
||||
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
||||
Oracle:(Gain the next level as a sorcery to add its ability.)\nLegendary creatures you control enter the battlefield with an additional +1/+1 counter on them.\n{R}{G}: Level 2\nLegendary spells you cast cost {R}{G} less to cast. This effect reduces only the amount of colored mana you pay.\n{3}{R}{G}: Level 3\nWhenever you cast a legendary spell, exile the top two cards of your library. You may play them this turn.
|
||||
18
forge-gui/res/cardsfolder/upcoming/cleric_class.txt
Normal file
18
forge-gui/res/cardsfolder/upcoming/cleric_class.txt
Normal file
@@ -0,0 +1,18 @@
|
||||
Name:Cleric Class
|
||||
ManaCost:W
|
||||
Types:Enchantment Class
|
||||
K:Class:3:3 W,4 W
|
||||
R:Event$ GainLife | ClassLevel$ 1 | ActiveZones$ Battlefield | ValidPlayer$ You | ReplaceWith$ ReplaceGainLife | Description$ If you would gain life, you gain that much life plus 1 instead.
|
||||
SVar:ReplaceGainLife:DB$ ReplaceEffect | VarName$ LifeGained | VarValue$ X
|
||||
SVar:X:ReplaceCount$LifeGained/Plus.1
|
||||
T:Mode$ LifeGained | ClassLevel$ 2 | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigPutCounter | TriggerDescription$ Whenever you gain life, put a +1/+1 counter on target creature you control.
|
||||
SVar:TrigPutCounter:DB$ PutCounter | ValidTgts$ Creature.YouCtrl | CounterType$ P1P1 | CounterNum$ 1
|
||||
T:Mode$ ClassLevelGained | ClassLevel$ 3 | ValidCard$ Card.Self | TriggerZones$ Battlefield | Execute$ TrigReanimate | TriggerDescription$ When this Class becomes level 3, return target creature card from your graveyard to the battlefield. You gain life equal to its toughness.
|
||||
SVar:TrigReanimate:DB$ ChangeZone | ValidTgts$ Creature.YouOwn | TgtPrompt$ Select target creature from your graveyard | Origin$ Graveyard | Destination$ Battlefield | RememberTargets$ True | SubAbility$ DBGainLife
|
||||
SVar:DBGainLife:DB$ GainLife | Defined$ You | LifeAmount$ Y | SubAbility$ DBCleanup
|
||||
SVar:DBCleanup:DB$Cleanup | ClearRemembered$ True
|
||||
SVar:Y:Remembered$CardToughness
|
||||
SVar:PlayMain1:True
|
||||
DeckNeeds:Ability$LifeGain
|
||||
DeckHas:Ability$Counters & Ability$Graveyard
|
||||
Oracle:(Gain the next level as a sorcery to add its ability.)\nIf you would gain life, you gain that much life plus 1 instead.\n{3}{W}: Level 2\nWhenever you gain life, put a +1/+1 counter on target creature you control.\n{4}{W}: Level 3\nWhen this Class becomes level 3, return target creature card from your graveyard to the battlefield. You gain life equal to its toughness.
|
||||
13
forge-gui/res/cardsfolder/upcoming/druid_class.txt
Normal file
13
forge-gui/res/cardsfolder/upcoming/druid_class.txt
Normal file
@@ -0,0 +1,13 @@
|
||||
Name:Druid Class
|
||||
ManaCost:1 G
|
||||
Types:Enchantment Class
|
||||
K:Class:3:2 G,4 G
|
||||
T:Mode$ ChangesZone | ClassLevel$ 1 | Origin$ Any | Destination$ Battlefield | ValidCard$ Land.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigGainLife | TriggerDescription$ Whenever a land enters the battlefield under your control, you gain 1 life.
|
||||
SVar:TrigGainLife:DB$GainLife | Defined$ You | LifeAmount$ 1
|
||||
S:Mode$ Continuous | ClassLevel$ 2 | Affected$ You | AdjustLandPlays$ 1 | Description$ You may play an additional land on each of your turns.
|
||||
T:Mode$ ClassLevelGained | ClassLevel$ 3 | ValidCard$ Card.Self | TriggerZones$ Battlefield | Execute$ TrigAnimateLand | TriggerDescription$ When this Class becomes level 3, target land you control becomes a creature with haste and "This creature's power and toughness are each equal to the number of lands you control." It's still a land.
|
||||
SVar:TrigAnimateLand:DB$ Animate | ValidTgts$ Land.YouCtrl | Types$ Creature | Duration$ Permanent | Keywords$ Haste | staticAbilities$ StLandPT
|
||||
SVar:StLandPT:Mode$ Continuous | EffectZone$ All | CharacteristicDefining$ True | SetPower$ X | SetToughness$ X | Description$ This creature's power and toughness are each equal to the number of lands you control.
|
||||
SVar:X:Count$Valid Land.YouCtrl
|
||||
DeckHas:Ability$LifeGain
|
||||
Oracle:(Gain the next level as a sorcery to add its ability.)\nWhenever a land enters the battlefield under your control, you gain 1 life.\n{2}{G}: Level 2\nYou may play an additional land on each of your turns.\n{4}{G}: Level 3\nWhen this Class becomes level 3, target land you control becomes a creature with haste and "This creature's power and toughness are each equal to the number of lands you control." It's still a land.
|
||||
10
forge-gui/res/cardsfolder/upcoming/fighter_class.txt
Normal file
10
forge-gui/res/cardsfolder/upcoming/fighter_class.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
Name:Fighter Class
|
||||
ManaCost:R W
|
||||
Types:Enchantment Class
|
||||
K:Class:3:1 R W,3 R W
|
||||
T:Mode$ ChangesZone | ClassLevel$ 1 | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigChange | TriggerDescription$ When CARDNAME enters the battlefield, search your library for an Equipment card, reveal it, put it into your hand, then shuffle.
|
||||
SVar:TrigChange:DB$ ChangeZone | Origin$ Library | Destination$ Hand | ChangeType$ Card.Equipment | ChangeNum$ 1
|
||||
S:Mode$ ReduceCost | ClassLevel$ 2 | ValidCard$ Card | ValidSpell$ Activated.Equip | Activator$ You | Amount$ 2 | Description$ Equip abilities you activate cost {2} less to activate.
|
||||
T:Mode$ Attacks | ClassLevel$ 3 | ValidCard$ Creature.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigMustBlock | TriggerDescription$ Whenever a creature you control attacks, up to one target creature blocks it this combat if able.
|
||||
SVar:TrigMustBlock:DB$ MustBlock | ValidTgts$ Creature | TargetMin$ 0 | TargetMax$ 1 | DefinedAttacker$ TriggeredAttacker | BlockAllDefined$ True
|
||||
Oracle:(Gain the next level as a sorcery to add its ability.)\nWhen Fighter Class enters the battlefield, search your library for an Equipment card, reveal it, put it into your hand, then shuffle.\n{1}{R}{W}: Level 2\nEquip abilities you activate cost {2} less to activate.\n{3}{R}{W}: Level 3\nWhenever a creature you control attacks, up to one target creature blocks it this combat if able.
|
||||
15
forge-gui/res/cardsfolder/upcoming/monk_class.txt
Normal file
15
forge-gui/res/cardsfolder/upcoming/monk_class.txt
Normal file
@@ -0,0 +1,15 @@
|
||||
Name:Monk Class
|
||||
ManaCost:W U
|
||||
Types:Enchantment Class
|
||||
K:Class:3:W U,1 W U
|
||||
S:Mode$ ReduceCost | ClassLevel$ 1 | ValidCard$ Card | Type$ Spell | Activator$ You | Amount$ 1 | CheckSVar$ YouCastThisTurn | SVarCompare$ EQ1 | Description$ The second spell you cast each turn costs {1} less to cast.
|
||||
T:Mode$ ClassLevelGained | ClassLevel$ 2 | ValidCard$ Card.Self | TriggerZones$ Battlefield | Execute$ TrigBounce | TriggerDescription$ When this Class becomes level 2, return up to one target nonland permanent to its owner’s hand.
|
||||
SVar:TrigBounce:DB$ChangeZone | ValidTgts$ Permanent.nonLand | TargetMin$ 0 | TargetMax$ 1 | TgtPrompt$ Select target nonland permanent | Origin$ Battlefield | Destination$ Hand
|
||||
T:Mode$ Phase | ClassLevel$ 3 | Phase$ Upkeep | TriggerZones$ Battlefield | ValidPlayer$ You | Execute$ TrigExile | TriggerDescription$ At the beginning of your upkeep, exile the top card of your library. For as long as it remains exiled, it has "You may cast this card from exile as long as you've cast another spell this turn."
|
||||
SVar:TrigExile:DB$ Dig | Defined$ You | DigNum$ 1 | ChangeNum$ All | DestinationZone$ Exile | RememberChanged$ True | SubAbility$ DBMayPlay
|
||||
SVar:DBMayPlay:DB$ Animate | Defined$ Remembered | staticAbilities$ StPlay | Duration$ Permanent | SubAbility$ DBCleanup
|
||||
SVar:StPlay:Mode$ Continuous | MayPlay$ True | EffectZone$ Exile | Affected$ Card.Self+nonLand | AffectedZone$ Exile | CheckSVar$ YouCastThisTurn | SVarCompare$ GE1 | Description$ You may cast this card from exile as long as you've cast another spell this turn.
|
||||
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
||||
SVar:YouCastThisTurn:Count$ThisTurnCast_Card.YouCtrl
|
||||
SVar:PlayMain1:TRUE
|
||||
Oracle:(Gain the next level as a sorcery to add its ability.)\nThe second spell you cast each turn costs {1} less to cast.\n{W}{U}: Level 2\nWhen this Class becomes level 2, return up to one target nonland permanent to its owner’s hand.\n{1}{W}{U}: Level 3\nAt the beginning of your upkeep, exile the top card of your library. For as long as it remains exiled, it has "You may cast this card from exile as long as you've cast another spell this turn."
|
||||
10
forge-gui/res/cardsfolder/upcoming/paladin_class.txt
Normal file
10
forge-gui/res/cardsfolder/upcoming/paladin_class.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
Name:Paladin Class
|
||||
ManaCost:W
|
||||
Types:Enchantment Class
|
||||
K:Class:3:2 W,4 W
|
||||
S:Mode$ RaiseCost | ClassLevel$ 1 | ValidCard$ Card | Activator$ Opponent | ValidSpell$ Spell | Amount$ 1 | Condition$ PlayerTurn | Description$ Spells your opponents cast during your turn cost {1} more to cast.
|
||||
S:Mode$ Continuous | ClassLevel$ 2 | Affected$ Creature.YouCtrl | AddPower$ 1 | AddToughness$ 1 | Description$ Creatures you control get +1/+1.
|
||||
T:Mode$ AttackersDeclared | ClassLevel$ 3 | AttackingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigPump | TriggerDescription$ Whenever you attack, until end of turn, target attacking creature gets +1/+1 for each other attacking creature and gains double strike.
|
||||
SVar:TrigPump:DB$ Pump | ValidTgts$ Creature.attacking | NumAtt$ X | NumDef$ X | KW$ Double Strike
|
||||
SVar:X:Count$Valid Creature.attacking/Minus.1
|
||||
Oracle:(Gain the next level as a sorcery to add its ability.)\nSpells your opponents cast during your turn cost {1} more to cast.\n{2}{W}: Level 2\nCreatures you control get +1/+1.\n{4}{W}: Level 3\nWhenever you attack, until end of turn, target attacking creature gets +1/+1 for each other attacking creature and gains double strike.
|
||||
12
forge-gui/res/cardsfolder/upcoming/ranger_class.txt
Normal file
12
forge-gui/res/cardsfolder/upcoming/ranger_class.txt
Normal file
@@ -0,0 +1,12 @@
|
||||
Name:Ranger Class
|
||||
ManaCost:1 G
|
||||
Types:Enchantment Class
|
||||
K:Class:3:1 G,3 G
|
||||
T:Mode$ ChangesZone | ClassLevel$ 1 | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigToken | TriggerDescription$ When CARDNAME enters the battlefield, create a 2/2 green Wolf creature token.
|
||||
SVar:TrigToken:DB$ Token | TokenAmount$ 1 | TokenScript$ g_2_2_wolf | TokenOwner$ You
|
||||
T:Mode$ AttackersDeclared | ClassLevel$ 2 | AttackingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigPutCounter | TriggerDescription$ Whenever you attack, put a +1/+1 counter on target attacking creature.
|
||||
SVar:TrigPutCounter:DB$ PutCounter | ValidTgts$ Creature.attacking | TgtPrompt$ Select target attacking creature | CounterType$ P1P1 | CounterNum$ 1
|
||||
S:Mode$ Continuous | ClassLevel$ 3 | Affected$ Card.TopLibrary+YouCtrl | AffectedZone$ Library | MayLookAt$ Player | Description$ You may look at the top card of your library any time.
|
||||
S:Mode$ Continuous | ClassLevel$ 3 | Affected$ Creature.nonLand+TopLibrary+YouCtrl | AffectedZone$ Library | MayPlay$ True | Description$ You may cast creature spells from the top of your library.
|
||||
DeckHas:Ability$Token & Ability$Counter
|
||||
Oracle:(Gain the next level as a sorcery to add its ability.)\nWhen Ranger Class enters the battlefield, create a 2/2 green Wolf creature token.\n{1}{G}: Level 2\nWhenever you attack, put a +1/+1 counter on target attacking creature.\n{3}{G}: Level 3\nYou may look at the top card of your library any time.\nYou may cast creature spells from the top of your library.
|
||||
14
forge-gui/res/cardsfolder/upcoming/rogue_class.txt
Normal file
14
forge-gui/res/cardsfolder/upcoming/rogue_class.txt
Normal file
@@ -0,0 +1,14 @@
|
||||
Name:Rogue Class
|
||||
ManaCost:U B
|
||||
Types:Enchantment Class
|
||||
K:Class:3:1 U B,2 U B
|
||||
T:Mode$ ChangesZone | ValidCard$ Card.IsRemembered | Origin$ Exile | ExcludedDestinations$ Stack | Destination$ Any | TriggerZones$ Battlefield | Execute$ TrigForget | Static$ True
|
||||
T:Mode$ SpellCast | ValidCard$ Card.IsRemembered | TriggerZones$ Battlefield | Execute$ TrigForget | Static$ True
|
||||
SVar:TrigForget:DB$ Pump | ForgetObjects$ TriggeredCard
|
||||
T:Mode$ DamageDone | ClassLevel$ 1 | ValidSource$ Creature.YouCtrl | ValidTarget$ Player | CombatDamage$ True | Execute$ TrigDig | TriggerZones$ Battlefield | TriggerDescription$ Whenever a creature you control deals combat damage to a player, exile the top card of that player's library face down. You may look at it for as long as it remains exiled.
|
||||
SVar:TrigDig:DB$ Dig | DigNum$ 1 | Defined$ TriggeredTarget | DestinationZone$ Exile | ExileFaceDown$ True | RememberChanged$ True | ChangeNum$ All
|
||||
S:Mode$ Continuous | ClassLevel$ 1 | MayLookAt$ You | EffectZone$ Battlefield | Affected$ Card.IsRemembered | AffectedZone$ Exile
|
||||
S:Mode$ Continuous | ClassLevel$ 2 | Affected$ Creature.YouCtrl | AddKeyword$ Menace | Description$ Creatures you control have menace.
|
||||
S:Mode$ Continuous | ClassLevel$ 3 | MayPlay$ True | MayPlayIgnoreType$ True | EffectZone$ Battlefield | Affected$ Card.IsRemembered | AffectedZone$ Exile | Description$ You may play cards exiled with CARDNAME, and you may spend mana as though it were mana of any color to cast those spells.
|
||||
SVar:PlayMain1:TRUE
|
||||
Oracle:(Gain the next level as a sorcery to add its ability.)\nWhenever a creature you control deals combat damage to a player, exile the top card of that player's library face down. You may look at it for as long as it remains exiled.\n{1}{U}{B}: Level 2\nCreatures you control have menace.\n{2}{U}{B}: Level 3\nYou may play cards exiled with Rogue Class, and you may spend mana as though it were mana of any color to cast those spells.
|
||||
14
forge-gui/res/cardsfolder/upcoming/sorcerer_class.txt
Normal file
14
forge-gui/res/cardsfolder/upcoming/sorcerer_class.txt
Normal file
@@ -0,0 +1,14 @@
|
||||
Name:Sorcerer Class
|
||||
ManaCost:U R
|
||||
Types:Enchantment Class
|
||||
K:Class:3:U R,3 U R
|
||||
T:Mode$ ChangesZone | ClassLevel$ 1 | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigDraw | TriggerDescription$ When CARDNAME enters the battlefield, draw two cards, then discard two cards.
|
||||
SVar:TrigDraw:DB$ Draw | NumCards$ 2 | SubAbility$ DBDiscard
|
||||
SVar:DBDiscard:DB$Discard | Defined$ You | NumCards$ 2 | Mode$ TgtChoose
|
||||
S:Mode$ Continuous | ClassLevel$ 2 | EffectZone$ Battlefield | Affected$ Creature.YouCtrl | AddAbility$ ManaU & ManaR | Description$ Creatures you control have "{T}: Add {U} or {R}. Spend this mana only to cast an instant or sorcery spell or to gain a Class level."
|
||||
SVar:ManaU:AB$Mana | Cost$ T | Produced$ U | Amount$ 1 | RestrictValid$ Instant,Sorcery,Activated.ClassLevelUp | SpellDescription$ Add {U}. Spend this mana only to cast an instant or sorcery spell or to gain a Class level.
|
||||
SVar:ManaR:AB$Mana | Cost$ T | Produced$ R | Amount$ 1 | RestrictValid$ Instant,Sorcery,Activated.ClassLevelUp | SpellDescription$ Add {R}. Spend this mana only to cast an instant or sorcery spell or to gain a Class level.
|
||||
T:Mode$ SpellCast | ClassLevel$ 3 | ValidCard$ Instant,Sorcery | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigDealDamage | TriggerDescription$ Whenever you cast an instant or sorcery spell, that spell deals damage to each opponent equal to the number of instant or sorcery spells you've cast this turn.
|
||||
SVar:TrigDealDamage:DB$ DamageAll | ValidPlayers$ Player.Opponent | NumDmg$ X | DamageSource$ TriggeredCard
|
||||
SVar:X:Count$ThisTurnCast_Instant.YouCtrl,Sorcery.YouCtrl
|
||||
Oracle:(Gain the next level as a sorcery to add its ability.)\nWhen Sorcerer Class enters the battlefield, draw two cards, then discard two cards.\n{U}{R}: Level 2\nCreatures you control have "{T}: Add {U} or {R}. Spend this mana only to cast an instant or sorcery spell or to gain a Class level."\n{3}{U}{R}: Level 3\nWhenever you cast an instant or sorcery spell, that spell deals damage to each opponent equal to the number of instant or sorcery spells you've cast this turn.
|
||||
15
forge-gui/res/cardsfolder/upcoming/warlock_class.txt
Normal file
15
forge-gui/res/cardsfolder/upcoming/warlock_class.txt
Normal file
@@ -0,0 +1,15 @@
|
||||
Name:Warlock Class
|
||||
ManaCost:B
|
||||
Types:Enchantment Class
|
||||
K:Class:3:1 B,6 B
|
||||
T:Mode$ Phase | ClassLevel$ 1 | Phase$ End of Turn | ValidPlayer$ You | TriggerZones$ Battlefield | CheckSVar$ X | SVarCompare$ GE1 | Execute$ TrigLose1 | TriggerDescription$ At the beginning of your end step, if a creature died this turn, each opponent loses 1 life.
|
||||
SVar:TrigLose1:DB$ LoseLife | Defined$ Player.Opponent | LifeAmount$ 1
|
||||
SVar:X:Count$ThisTurnEntered_Graveyard_from_Battlefield_Creature
|
||||
T:Mode$ ClassLevelGained | ClassLevel$ 2 | ValidCard$ Card.Self | TriggerZones$ Battlefield | Execute$ TrigDig | TriggerDescription$ When this Class becomes level 2, look at the top three cards of your library. Put one of them into your hand and the rest into your graveyard.
|
||||
SVar:TrigDig:DB$ Dig | DigNum$ 3 | DestinationZone2$ Graveyard
|
||||
T:Mode$ Phase | ClassLevel$ 3 | Phase$ End of Turn | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ RepeatOpps | TriggerDescription$ At the beginning of your end step, each opponent loses life equal to the life they lost this turn. (Damage causes loss of life.)
|
||||
SVar:RepeatOpps:DB$ RepeatEach | RepeatPlayers$ Player.Opponent | RepeatSubAbility$ TrigLoseAgain
|
||||
SVar:TrigLoseAgain:DB$ LoseLife | Defined$ Remembered | LifeAmount$ Y
|
||||
SVar:Y:PlayerCountRemembered$LifeLostThisTurn
|
||||
DeckHas:Ability$Graveyard
|
||||
Oracle:(Gain the next level as a sorcery to add its ability.)\nAt the beginning of your end step, if a creature died this turn, each opponent loses 1 life.\n{1}{B}: Level 2\nWhen this Class becomes level 2, look at the top three cards of your library. Put one of them into your hand and the rest into your graveyard.\n{6}{B}: Level 2\nAt the beginning of your end step, each opponent loses life equal to the life they lost this turn. (Damage causes loss of life.)
|
||||
11
forge-gui/res/cardsfolder/upcoming/wizard_class.txt
Normal file
11
forge-gui/res/cardsfolder/upcoming/wizard_class.txt
Normal file
@@ -0,0 +1,11 @@
|
||||
Name:Wizard Class
|
||||
ManaCost:U
|
||||
Types:Enchantment Class
|
||||
K:Class:3:2 U,4 U
|
||||
S:Mode$ Continuous | ClassLevel$ 1 | EffectZone$ Battlefield | Affected$ You | SetMaxHandSize$ Unlimited | Description$ You have no maximum hand size.
|
||||
T:Mode$ ClassLevelGained | ClassLevel$ 2 | ValidCard$ Card.Self | TriggerZones$ Battlefield | Execute$ TrigDraw | TriggerDescription$ When this Class becomes level 2, draw two cards.
|
||||
SVar:TrigDraw:DB$ Draw | NumCards$ 2
|
||||
T:Mode$ Drawn | ClassLevel$ 3 | ValidCard$ Card.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigPutCounter | TriggerDescription$ Whenever you draw a card, put a +1/+1 counter on target creature you control.
|
||||
SVar:TrigPutCounter:DB$ PutCounter | ValidTgts$ Creature.YouCtrl | CounterType$ P1P1 | CounterNum$ 1
|
||||
DeckHas:Ability$Counters
|
||||
Oracle:(Gain the next level as a sorcery to add its ability.)\nYou have no maximum hand size.\n{2}{U}: Level 2\nWhen this Class becomes level 2, draw two cards.\n{4}{U}: Level 3\nWhenever you draw a card, put a +1/+1 counter on target creature you control.
|
||||
@@ -295,6 +295,7 @@ Trap
|
||||
[EnchantmentTypes]
|
||||
Aura
|
||||
Cartouche
|
||||
Class
|
||||
Curse
|
||||
Rune
|
||||
Saga
|
||||
|
||||
@@ -19,6 +19,7 @@ import forge.game.GameView;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.card.CardView;
|
||||
import forge.game.card.CardView.CardStateView;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.game.card.CounterType;
|
||||
import forge.item.InventoryItemFromSet;
|
||||
import forge.item.PaperCard;
|
||||
@@ -480,12 +481,20 @@ public class CardDetailUtil {
|
||||
// dungeon room
|
||||
if (card.getCurrentRoom() != null && !card.getCurrentRoom().isEmpty()) {
|
||||
if (area.length() != 0) {
|
||||
area.append("\n");
|
||||
area.append("\n\n");
|
||||
}
|
||||
area.append("(In room: ");
|
||||
area.append(card.getCurrentRoom()).append(")");
|
||||
}
|
||||
|
||||
// class level
|
||||
if (card.getId() >= 0 && card.getCurrentState().getType().hasStringType("Class") && card.getZone() == ZoneType.Battlefield) {
|
||||
if (area.length() != 0) {
|
||||
area.append("\n\n");
|
||||
}
|
||||
area.append("(Class Level:").append(card.getClassLevel()).append(")");
|
||||
}
|
||||
|
||||
// a card has something attached to it
|
||||
if (card.hasCardAttachments()) {
|
||||
if (area.length() != 0) {
|
||||
|
||||
Reference in New Issue
Block a user