Merge branch 'pwNumActivated' into 'master'

Pw num activated

Closes #963

See merge request core-developers/forge!1631
This commit is contained in:
Sol
2019-05-08 01:36:10 +00:00
19 changed files with 49 additions and 60 deletions

View File

@@ -1010,7 +1010,7 @@ public class AiController {
p += 9;
}
// sort planeswalker abilities with most costly first
if (sa.getRestrictions().isPwAbility()) {
if (sa.isPwAbility()) {
final CostPart cost = sa.getPayCosts().getCostParts().get(0);
if (cost instanceof CostRemoveCounter) {
p += cost.convertAmount() == null ? 1 : cost.convertAmount();

View File

@@ -481,7 +481,7 @@ public class ComputerUtilCost {
}
// Try not to lose Planeswalker if not threatened
if (sa.getRestrictions().isPwAbility()) {
if (sa.isPwAbility()) {
for (final CostPart part : sa.getPayCosts().getCostParts()) {
if (part instanceof CostRemoveCounter) {
if (part.convertAmount() != null && part.convertAmount() == sa.getHostCard().getCurrentLoyalty()) {

View File

@@ -247,7 +247,7 @@ public abstract class SpellAbilityAi {
protected static boolean isSorcerySpeed(final SpellAbility sa) {
return (sa.getRootAbility().isSpell() && sa.getHostCard().isSorcery())
|| (sa.getRootAbility().isAbility() && sa.getRestrictions().isSorcerySpeed())
|| (sa.getRestrictions().isPwAbility() && !sa.getHostCard().hasKeyword("CARDNAME's loyalty abilities can be activated at instant speed."));
|| (sa.isPwAbility() && !sa.getHostCard().hasKeyword("CARDNAME's loyalty abilities can be activated at instant speed."));
}
/**
@@ -276,7 +276,7 @@ public abstract class SpellAbilityAi {
return true;
}
if (sa.getRestrictions().isPwAbility() && phase.is(PhaseType.MAIN2)) {
if (sa.isPwAbility() && phase.is(PhaseType.MAIN2)) {
return true;
}
if (sa.isSpell() && !sa.isBuyBackAbility()) {

View File

@@ -717,8 +717,7 @@ public class DamageDealAi extends DamageAiBase {
}
if (phase.is(PhaseType.MAIN2) && sa.isAbility()) {
if (sa.getRestrictions().isPwAbility()
|| source.hasSVar("EndOfTurnLeavePlay"))
if (sa.isPwAbility() || source.hasSVar("EndOfTurnLeavePlay"))
freePing = true;
}
}

View File

@@ -78,7 +78,7 @@ public class TokenAi extends SpellAbilityAi {
// Planeswalker-related flags
boolean pwMinus = false;
boolean pwPlus = false;
if (sa.getRestrictions().isPwAbility()) {
if (sa.isPwAbility()) {
/*
* Planeswalker token ability with loyalty costs should be played in
* Main1 or it might never be used due to other positive abilities.
@@ -230,7 +230,7 @@ public class TokenAi extends SpellAbilityAi {
alwaysOnOppAttack = aic.getBooleanProperty(AiProps.TOKEN_GENERATION_ALWAYS_IF_OPP_ATTACKS);
}
if (sa.getRestrictions() != null && sa.getRestrictions().isPwAbility() && alwaysFromPW) {
if (sa.isPwAbility() && alwaysFromPW) {
return true;
} else if (ai.getGame().getPhaseHandler().is(PhaseType.COMBAT_DECLARE_ATTACKERS)
&& ai.getGame().getPhaseHandler().getPlayerTurn().isOpponentOf(ai)

View File

@@ -324,11 +324,12 @@ public class GameCopier {
if (c.isPlaneswalker()) {
for (SpellAbility sa : c.getAllSpellAbilities()) {
SpellAbilityRestriction restrict = sa.getRestrictions();
if (restrict.isPwAbility() && restrict.getNumberTurnActivations() > 0) {
if (sa.isPwAbility() && restrict.getNumberTurnActivations() > 0) {
SpellAbility newSa = findSAInCard(sa, newCard);
if (newSa != null) {
for (int i = 0; i < restrict.getNumberTurnActivations(); i++) {
newSa.getRestrictions().abilityActivated();
newCard.addPlaneswalkerAbilityActivated();
}
}
}

View File

@@ -148,7 +148,7 @@ public class SpellAbilityPicker {
if (sa.isSpell()) {
return !sa.getHostCard().isInstant() && !sa.getHostCard().withFlash(player);
}
if (sa.getRestrictions().isPwAbility()) {
if (sa.isPwAbility()) {
return !sa.getHostCard().hasKeyword("CARDNAME's loyalty abilities can be activated at instant speed.");
}
return sa.isAbility() && sa.getRestrictions().isSorcerySpeed();

View File

@@ -72,9 +72,7 @@ public class GameAction {
public final void resetActivationsPerTurn() {
// Reset Activations per Turn
for (final Card card : game.getCardsInGame()) {
for (final SpellAbility sa : card.getAllSpellAbilities()) {
sa.getRestrictions().resetTurnActivations();
}
card.resetActivationsPerTurn();
}
}

View File

@@ -267,6 +267,8 @@ public class Card extends GameEntity implements Comparable<Card> {
private SpellAbility[] basicLandAbilities = new SpellAbility[MagicColor.WUBRG.length];
private int planeswalkerAbilityActivated = 0;
// Enumeration for CMC request types
public enum SplitCMCMode {
CurrentSideCMC,
@@ -6183,4 +6185,19 @@ public class Card extends GameEntity implements Comparable<Card> {
return true;
}
public int getPlaneswalkerAbilityActivated() {
return planeswalkerAbilityActivated;
}
public void addPlaneswalkerAbilityActivated() {
planeswalkerAbilityActivated++;
}
public void resetActivationsPerTurn() {
planeswalkerAbilityActivated = 0;
for (final SpellAbility sa : this.getAllSpellAbilities()) {
sa.getRestrictions().resetTurnActivations();
}
}
}

View File

@@ -19,7 +19,7 @@ public class AchievementTracker {
public void onSpellAbilityPlayed(final SpellAbility sa) {
final Card card = sa.getHostCard();
if (sa.getRestrictions().isPwAbility() && sa.hasParam("Ultimate")) {
if (sa.isPwAbility() && sa.hasParam("Ultimate")) {
activatedUltimates.add(card.getName());
}
if (card.determineColor().equals(ColorSet.ALL_COLORS)) {

View File

@@ -264,7 +264,7 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit
}
// without a target
if (usesTargeting()) { return false; }
if (restrictions != null && restrictions.isPwAbility()) {
if (isPwAbility()) {
return false; //Loyalty ability, not a mana ability.
}
if (isWrapper() && ((WrappedAbility) this).getTrigger().getMode() != TriggerType.TapsForMana) {
@@ -438,6 +438,11 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit
return hasParam("IsCurse");
}
public final boolean isPwAbility() {
// TODO try to check the Cost itself
return hasParam("Planeswalker");
}
// begin - Input methods
public Cost getPayCosts() {

View File

@@ -153,10 +153,6 @@ public class SpellAbilityRestriction extends SpellAbilityVariables {
this.setColorToCheck(params.get("ActivationChosenColor"));
}
if (params.containsKey("Planeswalker")) {
this.setPwAbility(true);
}
if (params.containsKey("IsPresent")) {
this.setIsPresent(params.get("IsPresent"));
if (params.containsKey("PresentCompare")) {
@@ -482,7 +478,7 @@ public class SpellAbilityRestriction extends SpellAbilityVariables {
}
}
if (this.isPwAbility()) {
if (sa.isPwAbility()) {
if (!c.hasKeyword("CARDNAME's loyalty abilities can be activated at instant speed.")
&& !activator.canCastSorcery()) {
return false;
@@ -491,15 +487,7 @@ public class SpellAbilityRestriction extends SpellAbilityVariables {
final int initialLimit = c.hasKeyword("CARDNAME's loyalty abilities can be activated twice each turn rather than only once") ? 1 : 0;
final int limits = c.getAmountOfKeyword("May activate CARDNAME's loyalty abilities once") + initialLimit;
int numActivates = 0;
for (final SpellAbility pwAbs : c.getAllSpellAbilities()) {
// check all abilities on card that have their planeswalker
// restriction set to confirm they haven't been activated
final SpellAbilityRestriction restrict = pwAbs.getRestrictions();
if (restrict.isPwAbility()) {
numActivates += restrict.getNumberTurnActivations();
}
}
int numActivates = c.getPlaneswalkerAbilityActivated();
if (numActivates > limits) {
return false;
}

View File

@@ -90,7 +90,6 @@ public class SpellAbilityVariables implements Cloneable {
this.manaSpent = sav.getManaSpent();
this.targetValidTargeting = sav.getTargetValidTargeting();
this.targetsSingleTarget = sav.targetsSingleTarget();
this.pwAbility = sav.isPwAbility();
this.presenceCondition = sav.getPresenceCondition();
}
@@ -197,9 +196,6 @@ public class SpellAbilityVariables implements Cloneable {
/** The mana spent. */
private String manaSpent = "";
/** The pw ability. */
private boolean pwAbility = false;
/** The chosen colors string. */
private String chosenColors = null;
@@ -674,25 +670,6 @@ public class SpellAbilityVariables implements Cloneable {
this.shareAllColors = shareAllColors;
}
/**
* Checks if is pw ability.
*
* @return the pwAbility
*/
public final boolean isPwAbility() {
return this.pwAbility;
}
/**
* Sets the pw ability.
*
* @param pwAbility0
* the new pw ability
*/
public final void setPwAbility(final boolean pwAbility0) {
this.pwAbility = pwAbility0;
}
/**
* Checks if is player turn.
*

View File

@@ -126,11 +126,11 @@ public class StaticAbilityCantBeCast {
return false;
}
if (params.containsKey("NonLoyalty") && (spellAbility.getRestrictions().isPwAbility())) {
if (params.containsKey("NonLoyalty") && spellAbility.isPwAbility()) {
return false;
}
if (params.containsKey("Loyalty") && !(spellAbility.getRestrictions().isPwAbility())) {
if (params.containsKey("Loyalty") && !spellAbility.isPwAbility()) {
return false;
}

View File

@@ -394,7 +394,7 @@ public final class StaticAbilityContinuous {
for (Card c : cardsIGainedAbilitiesFrom) {
for (SpellAbility sa : c.getSpellAbilities()) {
if (sa instanceof AbilityActivated) {
if (loyaltyAB && !sa.getRestrictions().isPwAbility()) {
if (loyaltyAB && !sa.isPwAbility()) {
continue;
}
SpellAbility newSA = sa.copy(hostCard, false);

View File

@@ -133,16 +133,20 @@ public class MagicStack /* extends MyObservable */ implements Iterable<SpellAbil
}
public final void addAndUnfreeze(final SpellAbility ability) {
final Card source = ability.getHostCard();
if (!ability.isCopied()) {
// Copied abilities aren't activated, so they shouldn't change these values
ability.getRestrictions().abilityActivated();
if (ability.isPwAbility()) {
source.addPlaneswalkerAbilityActivated();
}
ability.checkActivationResloveSubs();
}
// if the ability is a spell, but not a copied spell and its not already
// on the stack zone, move there
if (ability.isSpell()) {
final Card source = ability.getHostCard();
if (!source.isCopiedSpell() && !source.isInZone(ZoneType.Stack)) {
ability.setHostCard(game.getAction().moveToStack(source, ability, null));
}
@@ -491,7 +495,7 @@ public class MagicStack /* extends MyObservable */ implements Iterable<SpellAbil
thisTurnCast.add(sp.getHostCard());
sp.getActivatingPlayer().addSpellCastThisTurn();
}
if (sp.isAbility() && sp.getRestrictions().isPwAbility()) {
if (sp.isAbility() && sp.isPwAbility()) {
sp.getActivatingPlayer().setActivateLoyaltyAbilityThisTurn(true);
}
game.updateStackForView();

View File

@@ -3,7 +3,7 @@ ManaCost:2 U U
Types:Legendary Creature Zombie God
PT:4/5
K:Flying
T:Mode$ Drawn | ValidCard$ Card.YouOwn | Number$ 1 | OptionalDecider$ You | Static$ True | Execute$ DBReveal | TriggerDescription$ You may reveal the first card you draw each turn as you draw it. Whenever you reveal an instant or sorcery card this way, copy that card and you may cast the copy. That copy costs {2} less to cast.
T:Mode$ Drawn | ValidCard$ Card.YouOwn | Number$ 1 | OptionalDecider$ You | Static$ True | Execute$ DBReveal | TriggerZones$ Battlefield | TriggerDescription$ You may reveal the first card you draw each turn as you draw it. Whenever you reveal an instant or sorcery card this way, copy that card and you may cast the copy. That copy costs {2} less to cast.
SVar:DBReveal:DB$ Reveal | Defined$ You | RevealDefined$ TriggeredCard | RememberRevealed$ True | SubAbility$ DBTrigger | AILogic$ Kefnet
SVar:DBTrigger:DB$ ImmediateTrigger | RememberObjects$ RememberedCard | ConditionDefined$ Remembered | ConditionPresent$ Instant,Sorcery | SubAbility$ DBCleanup | Execute$ DBPlay | TriggerDescription$ Whenever you reveal an instant or sorcery card this way, copy that card and you may cast the copy. That copy costs {2} less to cast.
SVar:DBPlay:DB$ Play | Defined$ DelayTriggerRemembered | PlayReduceCost$ 2 | CopyOnce$ True | Optional$ True | CopyCard$ True

View File

@@ -6,6 +6,6 @@ K:Riot
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigCharm | TriggerDescription$ When CARDNAME enters the battlefield, ABILITY
SVar:TrigCharm:DB$ Charm | MinCharmNum$ 0 | CharmNum$ 1 | Choices$ DBFight,DBDestroy
SVar:DBFight:DB$ Fight | Defined$ TriggeredCardLKICopy | ValidTgts$ Creature.YouDontCtrl | TgtPrompt$ Choose target creature you don't control | SpellDescription$ CARDNAME fights target creature you don't control.
SVar:DBDestroy:DB$ Destroy | ValidTgts$ Land.hasNonManaActivatedAbility | TgtPrompt$ Select target land with an activated ability that isn't a mana ability | SpellDescription$ Destroy target land with an activated ability that iasn't a mana ability.
SVar:DBDestroy:DB$ Destroy | ValidTgts$ Land.hasNonManaActivatedAbility | TgtPrompt$ Select target land with an activated ability that isn't a mana ability | SpellDescription$ Destroy target land with an activated ability that isn't a mana ability.
DeckHas:Ability$Counters
Oracle:Riot (This creature enters the battlefield with your choice of a +1/+1 counter or haste.)\nWhen Ravager Wurm enters the battlefield, choose up to one -\n- Ravager Wurm fights target creature you don't control.\n- Destroy target land with an activated ability that isn't a mana ability.

View File

@@ -1011,7 +1011,7 @@ public class HumanCostDecision extends CostDecisionMakerBase {
}
else if (c == null && "XChoice".equals(sVarAmount)) {
cntRemoved = chooseXValue(maxCounters);
} else if (ability != null && !ability.getRestrictions().isPwAbility()) {
} else if (ability != null && !ability.isPwAbility()) {
// ignore Planeswalker abilities for this
if (maxCounters < cntRemoved) {
return null;