Merge branch 'fixstuff' into 'master'

Some smaller fixes

Closes #1868

See merge request core-developers/forge!4806
This commit is contained in:
Michael Kamensky
2021-06-03 14:02:50 +00:00
16 changed files with 24 additions and 24 deletions

View File

@@ -313,7 +313,6 @@ public class AiController {
// need to set TriggeredObject // need to set TriggeredObject
exSA.setTriggeringObject(AbilityKey.Card, card); exSA.setTriggeringObject(AbilityKey.Card, card);
// for trigger test, need to ignore the conditions // for trigger test, need to ignore the conditions
SpellAbilityCondition cons = exSA.getConditions(); SpellAbilityCondition cons = exSA.getConditions();
if (cons != null) { if (cons != null) {

View File

@@ -193,7 +193,7 @@ public abstract class SpellAbilityAi {
* Handles the AI decision to play a triggered SpellAbility * Handles the AI decision to play a triggered SpellAbility
*/ */
protected boolean doTriggerAINoCost(final Player aiPlayer, final SpellAbility sa, final boolean mandatory) { protected boolean doTriggerAINoCost(final Player aiPlayer, final SpellAbility sa, final boolean mandatory) {
if (canPlayWithoutRestrict(aiPlayer, sa)) { if (canPlayWithoutRestrict(aiPlayer, sa) && (!mandatory || sa.isTargetNumberValid())) {
return true; return true;
} }

View File

@@ -400,7 +400,6 @@ public class PumpAi extends PumpAiBase {
if (ComputerUtilCard.shouldPumpCard(ai, sa, card, defense, attack, keywords, false)) { if (ComputerUtilCard.shouldPumpCard(ai, sa, card, defense, attack, keywords, false)) {
return true; return true;
} else if (containsUsefulKeyword(ai, keywords, card, sa, attack)) { } else if (containsUsefulKeyword(ai, keywords, card, sa, attack)) {
Card pumped = ComputerUtilCard.getPumpedCreature(ai, sa, card, 0, 0, keywords); Card pumped = ComputerUtilCard.getPumpedCreature(ai, sa, card, 0, 0, keywords);
if (game.getPhaseHandler().is(PhaseType.COMBAT_DECLARE_ATTACKERS, ai) if (game.getPhaseHandler().is(PhaseType.COMBAT_DECLARE_ATTACKERS, ai)
|| game.getPhaseHandler().is(PhaseType.COMBAT_BEGIN, ai)) { || game.getPhaseHandler().is(PhaseType.COMBAT_BEGIN, ai)) {

View File

@@ -44,7 +44,6 @@ public abstract class PumpAiBase extends SpellAbilityAi {
return false; return false;
} }
public boolean grantsUsefulExtraBlockOpts(final Player ai, final SpellAbility sa, final Card card, List<String> keywords) { public boolean grantsUsefulExtraBlockOpts(final Player ai, final SpellAbility sa, final Card card, List<String> keywords) {
PhaseHandler ph = ai.getGame().getPhaseHandler(); PhaseHandler ph = ai.getGame().getPhaseHandler();
Card pumped = ComputerUtilCard.getPumpedCreature(ai, sa, card, 0, 0, keywords); Card pumped = ComputerUtilCard.getPumpedCreature(ai, sa, card, 0, 0, keywords);
@@ -506,7 +505,6 @@ public abstract class PumpAiBase extends SpellAbilityAi {
else { else {
final boolean addsKeywords = !keywords.isEmpty(); final boolean addsKeywords = !keywords.isEmpty();
if (addsKeywords) { if (addsKeywords) {
// If the keyword can prevent a creature from attacking, see if there's some kind of viable prioritization // If the keyword can prevent a creature from attacking, see if there's some kind of viable prioritization
if (keywords.contains("CARDNAME can't attack.") || keywords.contains("CARDNAME can't attack or block.") if (keywords.contains("CARDNAME can't attack.") || keywords.contains("CARDNAME can't attack or block.")
|| keywords.contains("HIDDEN CARDNAME can't attack.") || keywords.contains("HIDDEN CARDNAME can't attack or block.")) { || keywords.contains("HIDDEN CARDNAME can't attack.") || keywords.contains("HIDDEN CARDNAME can't attack or block.")) {

View File

@@ -151,6 +151,12 @@ public class PumpAllAi extends PumpAiBase {
return true; return true;
} }
@Override
protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) {
// important to call canPlay first so targets are added if needed
return canPlayAI(ai, sa) || mandatory;
}
boolean pumpAgainstRemoval(Player ai, SpellAbility sa, List<Card> comp) { boolean pumpAgainstRemoval(Player ai, SpellAbility sa, List<Card> comp) {
final List<GameObject> objects = ComputerUtil.predictThreatenedObjects(sa.getActivatingPlayer(), sa, true); final List<GameObject> objects = ComputerUtil.predictThreatenedObjects(sa.getActivatingPlayer(), sa, true);
for (final Card c : comp) { for (final Card c : comp) {

View File

@@ -39,6 +39,4 @@ public class TapOrUntapAi extends TapAiBase {
return randomReturn; return randomReturn;
} }
} }

View File

@@ -772,7 +772,6 @@ public final class CardDb implements ICardDatabase, IDeckGenPool {
} }
public PaperCard createUnsupportedCard(String cardName) { public PaperCard createUnsupportedCard(String cardName) {
CardRequest request = CardRequest.fromString(cardName); CardRequest request = CardRequest.fromString(cardName);
CardEdition cardEdition = CardEdition.UNKNOWN; CardEdition cardEdition = CardEdition.UNKNOWN;
CardRarity cardRarity = CardRarity.Unknown; CardRarity cardRarity = CardRarity.Unknown;
@@ -813,7 +812,6 @@ public final class CardDb implements ICardDatabase, IDeckGenPool {
} }
return new PaperCard(CardRules.getUnsupportedCardNamed(request.cardName), cardEdition.getCode(), cardRarity, 1); return new PaperCard(CardRules.getUnsupportedCardNamed(request.cardName), cardEdition.getCode(), cardRarity, 1);
} }
private final Editor editor = new Editor(); private final Editor editor = new Editor();

View File

@@ -244,7 +244,6 @@ public class SpellAbilityCondition extends SpellAbilityVariables {
* @return a boolean. * @return a boolean.
*/ */
public final boolean areMet(final SpellAbility sa) { public final boolean areMet(final SpellAbility sa) {
Player activator = sa.getActivatingPlayer(); Player activator = sa.getActivatingPlayer();
if (activator == null) { if (activator == null) {
activator = sa.getHostCard().getController(); activator = sa.getHostCard().getController();

View File

@@ -3,7 +3,7 @@ ManaCost:5 R
Types:Creature Elemental Types:Creature Elemental
PT:6/6 PT:6/6
S:Mode$ ReduceCost | ValidCard$ Card.Self | Type$ Spell | Amount$ X | EffectZone$ All | Description$ This spell costs {X} less to cast, where X is the total amount of noncombat damage dealt to your opponents this turn. S:Mode$ ReduceCost | ValidCard$ Card.Self | Type$ Spell | Amount$ X | EffectZone$ All | Description$ This spell costs {X} less to cast, where X is the total amount of noncombat damage dealt to your opponents this turn.
SVar:X:PlayerCountOpponents$NonCombatDamageDealtThisTurn SVar:X:PlayerCountRegisteredOpponents$NonCombatDamageDealtThisTurn
K:Trample K:Trample
T:Mode$ DamageDone | ValidSource$ Card.YouCtrl,Emblem.YouCtrl | ValidTarget$ Opponent | CombatDamage$ False | TriggerZones$ Battlefield | Execute$ TrigDmg | TriggerDescription$ Whenever a source you control deals noncombat damage to an opponent, CARDNAME deals that much damage to target creature or planeswalker that player controls. T:Mode$ DamageDone | ValidSource$ Card.YouCtrl,Emblem.YouCtrl | ValidTarget$ Opponent | CombatDamage$ False | TriggerZones$ Battlefield | Execute$ TrigDmg | TriggerDescription$ Whenever a source you control deals noncombat damage to an opponent, CARDNAME deals that much damage to target creature or planeswalker that player controls.
SVar:TrigDmg:DB$ DealDamage | ValidTgts$ Creature,Planeswalker | TgtPrompt$ Select target creature or planeswalker that player controls | TargetsWithDefinedController$ TriggeredTarget | NumDmg$ Y SVar:TrigDmg:DB$ DealDamage | ValidTgts$ Creature,Planeswalker | TgtPrompt$ Select target creature or planeswalker that player controls | TargetsWithDefinedController$ TriggeredTarget | NumDmg$ Y

View File

@@ -2,6 +2,7 @@ Name:Draconic Intervention
ManaCost:2 R R ManaCost:2 R R
Types:Sorcery Types:Sorcery
A:SP$ DamageAll | Cost$ 2 R R ExileFromGrave<1/Instant;Sorcery> | NumDmg$ X | ValidCards$ Creature.nonDragon | RememberDamaged$ True | ReplaceDyingDefined$ Remembered | SubAbility$ DBCleanup | SpellDescription$ CARDNAME deals X damage to each non-Dragon creature, where X is the exiled cards mana value. If a creature dealt damage this way would die this turn, exile it instead. A:SP$ DamageAll | Cost$ 2 R R ExileFromGrave<1/Instant;Sorcery> | NumDmg$ X | ValidCards$ Creature.nonDragon | RememberDamaged$ True | ReplaceDyingDefined$ Remembered | SubAbility$ DBCleanup | SpellDescription$ CARDNAME deals X damage to each non-Dragon creature, where X is the exiled cards mana value. If a creature dealt damage this way would die this turn, exile it instead.
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True | SubAbility$ DBChange
SVar:DBChange:DB$ ChangeZone | Origin$ Stack | Destination$ Exile
SVar:X:Exiled$CardManaCost SVar:X:Exiled$CardManaCost
Oracle:As an additional cost to cast this spell, exile an instant or sorcery card from your graveyard.\nDraconic Intervention deals X damage to each non-Dragon creature, where X is the exiled card's mana value. If a creature dealt damage this way would die this turn, exile it instead.\nExile Draconic Intervention. Oracle:As an additional cost to cast this spell, exile an instant or sorcery card from your graveyard.\nDraconic Intervention deals X damage to each non-Dragon creature, where X is the exiled card's mana value. If a creature dealt damage this way would die this turn, exile it instead.\nExile Draconic Intervention.

View File

@@ -1,7 +1,7 @@
Name:Giant Opportunity Name:Giant Opportunity
ManaCost:2 G ManaCost:2 G
Types:Sorcery Types:Sorcery
A:SP$ Sacrifice | Cost$ 2 G | SacValid$ Food | Defined$ You | Amount$ 2 | Optional$ True | StrictAmount$ True | RememberSacrificed$ True | SubAbility$ DBToken | SpellDescription$ You may sacrifice two Foods. If you do, create a 7/7 green Giant creature token. Otherwise, create three Food tokens. (They're artifacts with "{2}, {T}, Sacrifice this artifact: You gain 3 life.") A:SP$ Sacrifice | Cost$ 2 G | SacValid$ Food | Defined$ You | Amount$ 2 | OptionalSacrifice$ True | StrictAmount$ True | RememberSacrificed$ True | SubAbility$ DBToken | SpellDescription$ You may sacrifice two Foods. If you do, create a 7/7 green Giant creature token. Otherwise, create three Food tokens. (They're artifacts with "{2}, {T}, Sacrifice this artifact: You gain 3 life.")
SVar:DBToken:DB$ Token | TokenAmount$ 1 | TokenScript$ g_7_7_giant | TokenOwner$ You | ConditionDefined$ RememberedLKI | ConditionPresent$ Food | ConditionCompare$ EQ2 | SubAbility$ DBToken2 SVar:DBToken:DB$ Token | TokenAmount$ 1 | TokenScript$ g_7_7_giant | TokenOwner$ You | ConditionDefined$ RememberedLKI | ConditionPresent$ Food | ConditionCompare$ EQ2 | SubAbility$ DBToken2
SVar:DBToken2:DB$ Token | TokenAmount$ 3 | TokenScript$ c_a_food_sac | TokenOwner$ You | ConditionDefined$ RememberedLKI | ConditionPresent$ Food | ConditionCompare$ EQ0 | SubAbility$ DBCleanup SVar:DBToken2:DB$ Token | TokenAmount$ 3 | TokenScript$ c_a_food_sac | TokenOwner$ You | ConditionDefined$ RememberedLKI | ConditionPresent$ Food | ConditionCompare$ EQ0 | SubAbility$ DBCleanup
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True

View File

@@ -5,5 +5,5 @@ A:SP$ Pump | Cost$ R | ValidTgts$ Creature.OppCtrl | AILogic$ PowerDmg | TgtProm
SVar:MutinyDamage:DB$ DealDamage | ValidTgts$ Creature.OppCtrl | TargetUnique$ True | AILogic$ PowerDmg | NumDmg$ X | DamageSource$ ParentTarget SVar:MutinyDamage:DB$ DealDamage | ValidTgts$ Creature.OppCtrl | TargetUnique$ True | AILogic$ PowerDmg | NumDmg$ X | DamageSource$ ParentTarget
SVar:X:ParentTargeted$CardPower SVar:X:ParentTargeted$CardPower
SVar:Picture:http://www.wizards.com/global/images/magic/general/mutiny.jpg SVar:Picture:http://www.wizards.com/global/images/magic/general/mutiny.jpg
//Not perfect yet, there seems to be no check whether the creature's controller is the same? //TODO Not perfect yet, there seems to be no check whether the creature's controller is the same?
Oracle:Target creature an opponent controls deals damage equal to its power to another target creature that player controls. Oracle:Target creature an opponent controls deals damage equal to its power to another target creature that player controls.

View File

@@ -4,6 +4,6 @@ Types:Legendary Creature Merfolk Rogue
PT:1/3 PT:1/3
T:Mode$ Phase | Phase$ End of Turn | TriggerZones$ Battlefield | Execute$ TrigDraw | OptionalDecider$ You | CheckSVar$ X | SVarCompare$ GE3 | TriggerDescription$ At the beginning of each end step, if an opponent lost 3 or more life this turn, you may draw a card. (Damage causes loss of life.) T:Mode$ Phase | Phase$ End of Turn | TriggerZones$ Battlefield | Execute$ TrigDraw | OptionalDecider$ You | CheckSVar$ X | SVarCompare$ GE3 | TriggerDescription$ At the beginning of each end step, if an opponent lost 3 or more life this turn, you may draw a card. (Damage causes loss of life.)
SVar:TrigDraw:DB$ Draw | Defined$ You | NumCards$ 1 SVar:TrigDraw:DB$ Draw | Defined$ You | NumCards$ 1
SVar:X:PlayerCountOpponents$HighestLifeLostThisTurn SVar:X:PlayerCountRegisteredOpponents$HighestLifeLostThisTurn
SVar:Picture:http://www.wizards.com/global/images/magic/general/sygg_river_cutthroat.jpg SVar:Picture:http://www.wizards.com/global/images/magic/general/sygg_river_cutthroat.jpg
Oracle:At the beginning of each end step, if an opponent lost 3 or more life this turn, you may draw a card. (Damage causes loss of life.) Oracle:At the beginning of each end step, if an opponent lost 3 or more life this turn, you may draw a card. (Damage causes loss of life.)

View File

@@ -66,6 +66,7 @@ public abstract class InputPayMana extends InputSyncronizedBase {
@Override @Override
protected void onStop() { protected void onStop() {
if (!isFinished()) {
// Clear current Mana cost being paid for SA // Clear current Mana cost being paid for SA
saPaidFor.setManaCostBeingPaid(null); saPaidFor.setManaCostBeingPaid(null);
player.popPaidForSA(); player.popPaidForSA();
@@ -74,6 +75,7 @@ public abstract class InputPayMana extends InputSyncronizedBase {
getController().getGui().hideManaPool(PlayerView.get(player)); getController().getGui().hideManaPool(PlayerView.get(player));
} }
} }
}
@Override @Override
protected boolean onCardSelected(final Card card, final List<Card> otherCardsToSelect, final ITriggerEvent triggerEvent) { protected boolean onCardSelected(final Card card, final List<Card> otherCardsToSelect, final ITriggerEvent triggerEvent) {

View File

@@ -36,8 +36,6 @@ public abstract class InputSyncronizedBase extends InputBase implements InputSyn
} }
protected final void stop() { protected final void stop() {
onStop();
// ensure input won't accept any user actions. // ensure input won't accept any user actions.
FThreads.invokeInEdtNowOrLater(new Runnable() { FThreads.invokeInEdtNowOrLater(new Runnable() {
@Override @Override
@@ -46,6 +44,8 @@ public abstract class InputSyncronizedBase extends InputBase implements InputSyn
} }
}); });
onStop();
// thread irrelevant // thread irrelevant
if (getController().getInputQueue().getInput() != null) { if (getController().getInputQueue().getInput() != null) {
getController().getInputQueue().removeInput(InputSyncronizedBase.this); getController().getInputQueue().removeInput(InputSyncronizedBase.this);