Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion forge-ai/src/main/java/forge/ai/SpellAbilityAi.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import forge.card.ICardFace;
import forge.card.mana.ManaCost;
import forge.game.GameEntity;
import forge.game.ability.IHasForgeParams;
import forge.game.card.Card;
import forge.game.card.CardCopyService;
import forge.game.card.CardState;
Expand All @@ -36,7 +37,12 @@
* <p>
* The three main methods are canPlayAI(), chkAIDrawback and doTriggerAINoCost.
*/
public abstract class SpellAbilityAi {
public abstract class SpellAbilityAi implements IHasForgeParams {
public static final String[] OPTIONAL_PARAMS = {
"AIActivateLast", "AIBidMax", "AICheckSVar", "AILifeThreshold", "AILogic",
"AIManaPref", "AIMaxTgtsCount", "AIPhyrexianPayment", "AIRespondsToOwnAbility",
"AISVarCompare", "AITgts", "AITgtsStrict", "AIXMax", "UnlessAI",
};

public Predicate<Card> CREATURE_OR_TAP_ABILITY = c -> {
if (c.isCreature()) {
Expand Down
13 changes: 12 additions & 1 deletion forge-game/src/main/java/forge/game/CardTraitBase.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import forge.card.MagicColor;
import forge.card.mana.ManaAtom;
import forge.game.ability.AbilityUtils;
import forge.game.ability.IHasForgeParams;
import forge.game.card.Card;
import forge.game.card.CardCollection;
import forge.game.card.CardLists;
Expand All @@ -36,7 +37,17 @@
* Base class for Triggers,ReplacementEffects and StaticAbilities.
*
*/
public abstract class CardTraitBase implements GameObject, IHasCardView, IHasSVars {
public abstract class CardTraitBase implements GameObject, IHasCardView, IHasSVars, IHasForgeParams {
public static final String[] OPTIONAL_PARAMS = {
"Adamant", "Blessing", "Bloodthirst", "CheckDefinedPlayer", "CheckSVar",
"CheckSecondSVar", "ClassLevel", "DayTime", "DefinedPlayerCompare", "Delirium",
"Desert", "FatefulHour", "Hellbent", "Invert", "IsPresent", "IsPresent2",
"LifeAmount", "LifeTotal", "ManaNotSpent", "ManaSpent", "Metalcraft", "Monarch",
"PresentCompare", "PresentCompare2", "PresentDefined", "PresentPlayer",
"PresentPlayer2", "PresentZone", "PresentZone2", "Revolt", "SVarCompare",
"SecondSVarCompare", "Secondary", "Threshold", "WerewolfTransformCondition",
"WerewolfUntransformCondition",
};

/** The host card. */
protected Card hostCard;
Expand Down
13 changes: 12 additions & 1 deletion forge-game/src/main/java/forge/game/ability/AbilityFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,18 @@
* @author Forge
* @version $Id$
*/
public final class AbilityFactory {
public final class AbilityFactory implements IHasForgeParams {
public static final String[] OPTIONAL_PARAMS = {
"BidSubAbility", "CantChooseSubAbility", "Choices", "ChooseNumberSubAbility",
"ChooseSubAbility", "ChosenPile", "Cost", "Execute", "FallbackAbility",
"FalseSubAbility", "GiftAbility", "GuessCorrect", "GuessWrong", "HeadsSubAbility",
"Highest", "LoseSubAbility", "Lowest", "MatchedAbility", "NonBasicSpell",
"NotLowest", "Origin", "OtherwiseSubAbility", "PreventionSubAbility",
"RegenerationAbility", "RepeatSubAbility", "ResultSubAbilities", "ReturnAbility",
"SpellDescription", "SubAbility", "TailsSubAbility", "TrueSubAbility",
"UnchosenPile", "UnmatchedAbility", "ValidTgts", "VoteSubAbility",
"VoteTiedAbility", "WinSubAbility",
};

public static final List<String> additionalAbilityKeys = Lists.newArrayList(
"WinSubAbility", "OtherwiseSubAbility", // Clash
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,14 @@
import java.util.stream.Collectors;
import java.util.stream.IntStream;

public class AbilityUtils {
public class AbilityUtils implements IHasForgeParams {
public static final String[] OPTIONAL_PARAMS = {
"AbilityCount", "AnnounceMax", "Destination", "ETB", "ForgetOtherTargets",
"IncludeAllComponentCards", "LockInText", "RememberCostMana", "RememberTargets",
"Triggered", "UnlessColor", "UnlessCost", "UnlessPayer", "UnlessResolveSubs",
"UnlessSwitched", "UnlessUpTo", "XMax", "XMin",
};

private final static ImmutableList<String> cmpList = ImmutableList.of("LT", "LE", "EQ", "GE", "GT", "NE");

// should the three getDefined functions be merged into one? Or better to
Expand Down
31 changes: 31 additions & 0 deletions forge-game/src/main/java/forge/game/ability/IHasForgeParams.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package forge.game.ability;

/**
* Implemented by classes that declare the card-script parameters they consume: the optional params
* in a {@code public static final String[] OPTIONAL_PARAMS} field, and (for effects) mutually-required
* groups in a {@code String[][] REQUIRED_PARAMS} field. The accessors expose those fields so the
* card-script linter can ask a class which params it accepts; CardScriptParamDeclarationTest discovers
* implementors by classpath scan and guards the declarations against drift.
*
* The accessors read the field of the runtime class ({@code getClass()}) rather than returning a field
* directly. Because the fields are {@code static}, a direct {@code return OPTIONAL_PARAMS} inherited by a
* subclass would return the superclass's field; reading {@code getClass()}'s field returns the subclass's
* own declaration (or the inherited one when it declares none), so no per-class override is needed.
*/
public interface IHasForgeParams {
default String[] getOptionalParams() {
try {
return (String[]) getClass().getField("OPTIONAL_PARAMS").get(null);
} catch (NoSuchFieldException | IllegalAccessException e) {
return new String[0];
}
}

default String[][] getRequiredParams() {
try {
return (String[][]) getClass().getField("REQUIRED_PARAMS").get(null);
} catch (NoSuchFieldException | IllegalAccessException e) {
return new String[0][];
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,16 @@
* @version $Id: AbilityFactoryAlterLife.java 17656 2012-10-22 19:32:56Z Max mtg $
*/

public abstract class SpellAbilityEffect {
public abstract class SpellAbilityEffect implements IHasForgeParams {
public static final String[] OPTIONAL_PARAMS = {
"AfterDescription", "Amount", "Announce", "AtEOTCondition", "AtEOTDesc",
"ConditionDescription", "Defined", "DefinedExiler", "Duration",
"ExiledWithEffectSource", "ForEach", "Forecast", "GiftDescription",
"IncludeAllComponentCards", "Named", "ReplaceDyingCondition", "ReplaceDyingDefined",
"ReplaceDyingExiledWith", "ReplaceDyingValid", "ReplaceDyingZone", "ReturnAbility",
"ReturnValid", "SpellDescription", "StackDescription", "StartingWith",
"ThisDefinedAndTgts",
};

public abstract void resolve(SpellAbility sa);

Expand Down
12 changes: 11 additions & 1 deletion forge-game/src/main/java/forge/game/cost/Cost.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import forge.card.CardType;
import forge.card.mana.ManaCost;
import forge.game.CardTraitBase;
import forge.game.ability.IHasForgeParams;
import forge.game.card.Card;
import forge.game.card.CounterEnumType;
import forge.game.card.CounterType;
Expand All @@ -46,7 +47,16 @@
* @author Forge
* @version $Id$
*/
public class Cost implements Serializable {
public class Cost implements Serializable, IHasForgeParams {
public static final String[] OPTIONAL_PARAMS = {
"AffectedZone", "Amount", "Announce", "Collected", "CollectedCards", "Color",
"Cost", "Exiled", "ExiledCards", "FirstForetell", "ForEachShard", "Foraged",
"ForagedCards", "IgnoreGeneric", "MinMana", "ModeCost", "OnlyFirstSpell",
"RaiseCost", "RaiseTo", "ReduceAmount", "ReduceCost", "Relative",
"SpellDescription", "TapCreaturesForMana", "Type", "UnlessValidTarget", "UpTo",
"ValidCard", "ValidSpell", "ValidTarget",
};

/**
* Serializables need a version ID.
*/
Expand Down
12 changes: 12 additions & 0 deletions forge-game/src/main/java/forge/game/spellability/SpellAbility.java
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,18 @@
* @version $Id$
*/
public abstract class SpellAbility extends CardTraitBase implements ISpellAbility, IIdentifiable, Comparable<SpellAbility> {
public static final String[] OPTIONAL_PARAMS = {
"AlternateCost", "Amount", "Announce", "Boast", "CantCopy", "CloakUp", "CostDesc",
"CumulativeUpkeep", "DisguiseUp", "DividedAsYouChoose", "Exhaust", "Hidden",
"IsCurse", "ManaRestriction", "ManifestUp", "MaxTotalTargetCMC",
"MaxTotalTargetPower", "MorphUp", "Origin", "Planeswalker", "PowerUp",
"PrecostDesc", "SpellDescription", "TargetType", "TargetingPlayer",
"TargetingPlayerControls", "TargetsWithControllerProperty",
"TargetsWithDefinedController", "TargetsWithRelatedProperty",
"TargetsWithSharedCardType", "TargetsWithSharedTypes", "Unlock", "ValidAfterStack",
"WithoutManaCost", "XColor",
};

private static int maxId = 0;
private static int nextId() { return ++maxId; }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import forge.game.GameObjectPredicates;
import forge.game.GameType;
import forge.game.ability.AbilityUtils;
import forge.game.ability.IHasForgeParams;
import forge.game.card.Card;
import forge.game.phase.PhaseHandler;
import forge.game.phase.PhaseType;
Expand All @@ -45,7 +46,21 @@
* @version $Id$
* @since 1.0.15
*/
public class SpellAbilityCondition extends SpellAbilityVariables {
public class SpellAbilityCondition extends SpellAbilityVariables implements IHasForgeParams {
public static final String[] OPTIONAL_PARAMS = {
"Condition", "ConditionActivationLimit", "ConditionCheckSVar",
"ConditionChosenColor", "ConditionCompare", "ConditionCompare2", "ConditionDefined",
"ConditionDefined2", "ConditionFirstCombat", "ConditionGameTypes",
"ConditionLifeAmount", "ConditionLifeTotal", "ConditionManaNotSpent",
"ConditionManaSpent", "ConditionNoDifferentColors", "ConditionNotPresent",
"ConditionOpponentTurn", "ConditionOptionalPaid", "ConditionPhases",
"ConditionPlayerContains", "ConditionPlayerDefined", "ConditionPlayerTurn",
"ConditionPresent", "ConditionPresent2", "ConditionSVarCompare",
"ConditionSorcerySpeed", "ConditionTargetValidTargeting",
"ConditionTargetsSingleTarget", "ConditionZone", "OrConditionCheckSVar",
"OrOtherConditionSVarCompare",
};

// A class for handling SpellAbility Conditions. These restrictions include:
// Zone, Phase, OwnTurn, Speed (instant/sorcery), Amount per Turn, Player,
// Threshold, Metalcraft, LevelRange, etc
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import forge.game.GameObjectPredicates;
import forge.game.GameType;
import forge.game.ability.AbilityUtils;
import forge.game.ability.IHasForgeParams;
import forge.game.card.*;
import forge.game.keyword.Keyword;
import forge.game.phase.PhaseType;
Expand All @@ -49,7 +50,17 @@
* @author Forge
* @version $Id$
*/
public class SpellAbilityRestriction extends SpellAbilityVariables {
public class SpellAbilityRestriction extends SpellAbilityVariables implements IHasForgeParams {
public static final String[] OPTIONAL_PARAMS = {
"Activation", "ActivationAfterBlockers", "ActivationFirstCombat",
"ActivationGameTypes", "ActivationLifeAmount", "ActivationLifeTotal",
"ActivationLimit", "ActivationPhases", "ActivationZone", "Activator",
"AdditionalActivationZone", "Affected", "CheckSVar", "ClassLevel",
"GameActivationLimit", "InstantSpeed", "IsPresent", "OpponentTurn", "PlayerTurn",
"PresentCompare", "PresentDefined", "PresentZone", "SVarCompare", "SorcerySpeed",
"ValidSA",
};

// A class for handling SpellAbility Restrictions. These restrictions include:
// Zone, Phase, OwnTurn, Speed (instant/sorcery), Amount per Turn, Player,
// Threshold, Metalcraft, LevelRange, etc
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import forge.game.Game;
import forge.game.GameEntity;
import forge.game.ability.AbilityUtils;
import forge.game.ability.IHasForgeParams;
import forge.game.card.Card;
import forge.game.player.Player;
import forge.game.zone.ZoneType;
Expand All @@ -42,7 +43,17 @@
* @author Forge
* @version $Id$
*/
public class TargetRestrictions {
public class TargetRestrictions implements IHasForgeParams {
public static final String[] OPTIONAL_PARAMS = {
"MaxTotalTargetCMC", "MaxTotalTargetPower", "RandomNumTargets", "TargetMax",
"TargetMin", "TargetUnique", "TargetValidTargeting", "TargetingPlayer",
"TargetsAtRandom", "TargetsForEachPlayer", "TargetsWithDifferentCMC",
"TargetsWithDifferentControllers", "TargetsWithDifferentNames",
"TargetsWithEqualToughness", "TargetsWithSameCardType", "TargetsWithSameController",
"TargetsWithSameCreatureType", "TargetsWithoutSameCreatureType", "TgtPrompt",
"TgtZone", "ValidTgts", "ValidTgtsDesc",
};

// Target has two things happening:
// Targeting restrictions (Creature, Min/Maxm etc) which are true for this
// What this Object is restricted to targeting
Expand Down
Loading
Loading