From bd7dfb8a273605ae40b2d36175ab49b51f05fdb7 Mon Sep 17 00:00:00 2001 From: tool4EvEr Date: Sun, 12 Feb 2023 14:11:34 +0100 Subject: [PATCH] Clean script --- .../forge/ai/ability/PermanentCreatureAi.java | 2 +- .../ability/effects/SacrificeAllEffect.java | 8 ++--- .../src/main/java/forge/game/card/Card.java | 9 ++++++ .../java/forge/game/cost/CostSacrifice.java | 31 ++++++++++--------- .../cardsfolder/a/animar_soul_of_elements.txt | 2 +- .../res/cardsfolder/p/primeval_spawn.txt | 4 +-- .../cardsfolder/t/the_first_tyrannic_war.txt | 8 ++--- .../java/forge/player/HumanCostDecision.java | 11 ++++--- 8 files changed, 40 insertions(+), 35 deletions(-) diff --git a/forge-ai/src/main/java/forge/ai/ability/PermanentCreatureAi.java b/forge-ai/src/main/java/forge/ai/ability/PermanentCreatureAi.java index 8afe150ecb3..fe90c642d56 100644 --- a/forge-ai/src/main/java/forge/ai/ability/PermanentCreatureAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/PermanentCreatureAi.java @@ -230,7 +230,7 @@ public class PermanentCreatureAi extends PermanentAi { * worth it. Not sure what 4. is for. 5. needs to be updated to ensure * that the net toughness is still positive after static effects. */ - final Card copy = CardUtil.getLKICopy(sa.getHostCard()); + final Card copy = CardUtil.getLKICopy(card); ComputerUtilCard.applyStaticContPT(game, copy, null); // AiPlayDecision.WouldBecomeZeroToughnessCreature return copy.getNetToughness() > 0 || copy.hasStartOfKeyword("etbCounter") || mana.countX() != 0 diff --git a/forge-game/src/main/java/forge/game/ability/effects/SacrificeAllEffect.java b/forge-game/src/main/java/forge/game/ability/effects/SacrificeAllEffect.java index cdd7b58744d..887e70ed0cb 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/SacrificeAllEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/SacrificeAllEffect.java @@ -67,14 +67,10 @@ public class SacrificeAllEffect extends SpellAbilityEffect { // update cards that where using LKI CardCollection gameList = new CardCollection(); for (Card sac : list) { - final Card gameCard = game.getCardState(sac, null); - // gameCard is LKI in that case, the card is not in game anymore - // or the timestamp did change - // this should check Self too - if (gameCard == null || !sac.equalsWithTimestamp(gameCard) || !gameCard.canBeSacrificedBy(sa, true)) { + if (!sac.canBeSacrificedBy(sa, true)) { continue; } - gameList.add(gameCard); + gameList.add(game.getCardState(sac, null)); } list = gameList; diff --git a/forge-game/src/main/java/forge/game/card/Card.java b/forge-game/src/main/java/forge/game/card/Card.java index 6e80eff9042..da78e518c25 100644 --- a/forge-game/src/main/java/forge/game/card/Card.java +++ b/forge-game/src/main/java/forge/game/card/Card.java @@ -6473,10 +6473,19 @@ public class Card extends GameEntity implements Comparable, IHasSVars { System.out.println("Trying to sacrifice immutables: " + this); return false; } + if (!isInPlay() || isPhasedOut()) { return false; } + final Card gameCard = game.getCardState(this, null); + // gameCard is LKI in that case, the card is not in game anymore + // or the timestamp did change + // this should check Self too + if (gameCard == null || !this.equalsWithTimestamp(gameCard)) { + return false; + } + return !StaticAbilityCantSacrifice.cantSacrifice(this, source, effect); } diff --git a/forge-game/src/main/java/forge/game/cost/CostSacrifice.java b/forge-game/src/main/java/forge/game/cost/CostSacrifice.java index 59bf5131025..b6f2f38fa0b 100644 --- a/forge-game/src/main/java/forge/game/cost/CostSacrifice.java +++ b/forge-game/src/main/java/forge/game/cost/CostSacrifice.java @@ -117,22 +117,25 @@ public class CostSacrifice extends CostPartWithList { Card originalEquipment = ability.getOriginalHost(); return originalEquipment.isEquipping() && originalEquipment.canBeSacrificedBy(ability, effect); } - else if (!payCostFromSource()) { // You can always sac all - if ("All".equalsIgnoreCase(getAmount())) { - CardCollectionView typeList = activator.getCardsIn(ZoneType.Battlefield); - typeList = CardLists.getValidCards(typeList, getType().split(";"), activator, source, ability); - // it needs to check if everything can be sacrificed - return Iterables.all(typeList, CardPredicates.canBeSacrificedBy(ability, effect)); - } - int amount = getAbilityAmount(ability); - - return getMaxAmountX(ability, activator, effect) >= amount; - // If amount is null, it's either "ALL" or "X" - // if X is defined, it needs to be calculated and checked, if X is - // choice, it can be Paid even if it's 0 + if (payCostFromSource()) { + return source.canBeSacrificedBy(ability, effect); } - else return source.canBeSacrificedBy(ability, effect); + + // You can always sac all + if ("All".equalsIgnoreCase(getAmount())) { + CardCollectionView typeList = activator.getCardsIn(ZoneType.Battlefield); + typeList = CardLists.getValidCards(typeList, getType().split(";"), activator, source, ability); + // it needs to check if everything can be sacrificed + return Iterables.all(typeList, CardPredicates.canBeSacrificedBy(ability, effect)); + } + + int amount = getAbilityAmount(ability); + + // If amount is null, it's either "ALL" or "X" + // if X is defined, it needs to be calculated and checked, if X is + // choice, it can be Paid even if it's 0 + return getMaxAmountX(ability, activator, effect) >= amount; } @Override diff --git a/forge-gui/res/cardsfolder/a/animar_soul_of_elements.txt b/forge-gui/res/cardsfolder/a/animar_soul_of_elements.txt index 5febe811cbb..080df8886d0 100644 --- a/forge-gui/res/cardsfolder/a/animar_soul_of_elements.txt +++ b/forge-gui/res/cardsfolder/a/animar_soul_of_elements.txt @@ -6,7 +6,7 @@ K:Protection from white K:Protection from black T:Mode$ SpellCast | ValidCard$ Creature | ValidActivatingPlayer$ You | Execute$ TrigPutCounter | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast a creature spell, put a +1/+1 counter on CARDNAME. SVar:TrigPutCounter:DB$ PutCounter | Defined$ Self | CounterType$ P1P1 | CounterNum$ 1 -S:Mode$ ReduceCost | ValidCard$ Creature | Type$ Spell | Activator$ You | Amount$ X | Description$ Creature spells you cast cost 1 less to cast for each +1/+1 counter on CARDNAME. +S:Mode$ ReduceCost | ValidCard$ Creature | Type$ Spell | Activator$ You | Amount$ X | Description$ Creature spells you cast cost 1 less to cast for each +1/+1 counter on NICKNAME. SVar:X:Count$CardCounters.P1P1 SVar:BuffedBy:Creature Oracle:Protection from white and from black\nWhenever you cast a creature spell, put a +1/+1 counter on Animar, Soul of Elements.\nCreature spells you cast cost {1} less to cast for each +1/+1 counter on Animar. diff --git a/forge-gui/res/cardsfolder/p/primeval_spawn.txt b/forge-gui/res/cardsfolder/p/primeval_spawn.txt index ab6d80d5ccc..e1415af567d 100644 --- a/forge-gui/res/cardsfolder/p/primeval_spawn.txt +++ b/forge-gui/res/cardsfolder/p/primeval_spawn.txt @@ -5,11 +5,9 @@ PT:10/10 K:Vigilance K:Trample K:Lifelink -R:Event$ Moved | ActiveZones$ Battlefield | Destination$ Battlefield | ValidCard$ Card.Self+wasNotCast | ReplaceWith$ Exile | Description$ If CARDNAME would enter the battlefield and it wasn't cast or no mana was spent to cast it, exile it instead. -R:Event$ Moved | ActiveZones$ Battlefield | Destination$ Battlefield | ValidCard$ Card.Self | CheckSVar$ X | SVarCompare$ EQ0 | ReplaceWith$ Exile | Description$ If CARDNAME would enter the battlefield and it wasn't cast or no mana was spent to cast it, exile it instead. +R:Event$ Moved | ActiveZones$ Battlefield | Destination$ Battlefield | ValidCard$ Card.Self+wasNotCast,Card.Self+CastSa Spell.ManaSpent EQ0 | ReplaceWith$ Exile | Description$ If CARDNAME would enter the battlefield and it wasn't cast or no mana was spent to cast it, exile it instead. SVar:Exile:DB$ ChangeZone | Hidden$ True | Origin$ All | Destination$ Exile | Defined$ ReplacedCard T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Any | ValidCard$ Card.Self | Execute$ TrigExile | TriggerDescription$ When CARDNAME leaves the battlefield, exile the top ten cards of your library. You may cast any number of spells with total mana value 10 or less from among them without paying their mana costs. SVar:TrigExile:DB$ Dig | Defined$ You | DigNum$ 10 | ChangeNum$ All | DestinationZone$ Exile | RememberChanged$ True | SubAbility$ DBPlay SVar:DBPlay:DB$ Play | Valid$ Card.nonLand+IsRemembered+YouOwn+cmcLE10 | WithTotalCMC$ 10 | ValidZone$ Exile | ValidSA$ Spell | Controller$ You | WithoutManaCost$ True | Optional$ True | Amount$ All -SVar:X:Count$CastTotalManaSpent Oracle:If Primeval Spawn would enter the battlefield and it wasn't cast or no mana was spent to cast it, exile it instead.\nVigilance, trample, lifelink\nWhen Primeval Spawn leaves the battlefield, exile the top ten cards of your library. You may cast any number of spells with total mana value 10 or less from among them without paying their mana costs. diff --git a/forge-gui/res/cardsfolder/t/the_first_tyrannic_war.txt b/forge-gui/res/cardsfolder/t/the_first_tyrannic_war.txt index a2494552c05..49c81b18bbf 100644 --- a/forge-gui/res/cardsfolder/t/the_first_tyrannic_war.txt +++ b/forge-gui/res/cardsfolder/t/the_first_tyrannic_war.txt @@ -2,11 +2,9 @@ Name:The First Tyrannic War ManaCost:2 G U R Types:Enchantment Saga K:Saga:3:DBChooseCard,DBDouble,DBDouble -SVar:DBChooseCard:DB$ ChooseCard | ChoiceZone$ Hand | Choices$ Creature.YouOwn | ChoiceTitle$ You may select a creature card | Optional$ True | SubAbility$ DBEffect | SpellDescription$ You may put a creature card from your hand onto the battlefield. If its mana cost contains {X}, it enters the battlefield with a number of +1/+1 counters on it equal to the number of lands you control. -SVar:DBEffect:DB$ Effect | ConditionDefined$ ChosenCard | ConditionPresent$ Card.hasXCost | ReplacementEffects$ ReplaceETB | RememberObjects$ ChosenCard | ExileOnMoved$ Hand | SubAbility$ DBPut -SVar:ReplaceETB:Event$ Moved | Origin$ Hand | Destination$ Battlefield | ValidCard$ Card.ChosenCard | ReplaceWith$ PutWithCounters | Description$ If its mana cost contains {X}, it enters the battlefield with a number of +1/+1 counters on it equal to the number of lands you control. -SVar:PutWithCounters:DB$ ChangeZone | Origin$ Hand | Destination$ Battlefield | Defined$ ChosenCard | WithCountersType$ P1P1 | WithCountersAmount$ Count$Valid Land.YouCtrl | SubAbility$ DBCleanup -SVar:DBPut:DB$ ChangeZone | Origin$ Hand | Destination$ Battlefield | Defined$ ChosenCard | SubAbility$ DBCleanup +SVar:DBChooseCard:DB$ ChooseCard | ChoiceZone$ Hand | Choices$ Creature.YouOwn | ChoiceTitle$ You may select a creature card | Optional$ True | SubAbility$ DBPutX | SpellDescription$ You may put a creature card from your hand onto the battlefield. If its mana cost contains {X}, it enters the battlefield with a number of +1/+1 counters on it equal to the number of lands you control. +SVar:DBPutX:DB$ ChangeZone | Origin$ Hand | Destination$ Battlefield | Defined$ ChosenCard | WithCountersType$ P1P1 | WithCountersAmount$ Count$Valid Land.YouCtrl | ConditionDefined$ ChosenCard | ConditionPresent$ Card.hasXCost | SubAbility$ DBPut +SVar:DBPut:DB$ ChangeZone | Origin$ Hand | Destination$ Battlefield | Defined$ ChosenCard | ConditionDefined$ ChosenCard | ConditionPresent$ Card.hasXCost | ConditionCompare$ EQ0 | SubAbility$ DBCleanup SVar:DBCleanup:DB$ Cleanup | ClearChosenCard$ True SVar:DBDouble:DB$ MultiplyCounter | ValidTgts$ Creature.YouCtrl | TgtPrompt$ Select target creature you control | Multiplier$ 2 | SpellDescription$ Double the number of each kind of counter on target creature you control. DeckHas:Ability$Counters diff --git a/forge-gui/src/main/java/forge/player/HumanCostDecision.java b/forge-gui/src/main/java/forge/player/HumanCostDecision.java index f0523fc8057..c09e669cdf6 100644 --- a/forge-gui/src/main/java/forge/player/HumanCostDecision.java +++ b/forge-gui/src/main/java/forge/player/HumanCostDecision.java @@ -1030,11 +1030,8 @@ public class HumanCostDecision extends CostDecisionMakerBase { final String amount = cost.getAmount(); final String type = cost.getType(); - CardCollectionView list = CardLists.filter(player.getCardsIn(ZoneType.Battlefield), CardPredicates.canBeSacrificedBy(ability, isEffect())); - list = CardLists.getValidCards(list, type.split(";"), player, source, ability); - if (cost.payCostFromSource()) { - if (source.getController() == ability.getActivatingPlayer() && source.isInPlay()) { + if (source.getController() == ability.getActivatingPlayer() && source.canBeSacrificedBy(ability, isEffect())) { return mandatory || confirmAction(cost, Localizer.getInstance().getMessage("lblSacrificeCardConfirm", CardTranslation.getTranslatedName(source.getName()))) ? PaymentDecision.card(source) : null; } return null; @@ -1042,12 +1039,15 @@ public class HumanCostDecision extends CostDecisionMakerBase { if (type.equals("OriginalHost")) { Card host = ability.getOriginalHost(); - if (host.getController() == ability.getActivatingPlayer() && host.isInPlay()) { + if (host.getController() == ability.getActivatingPlayer() && host.canBeSacrificedBy(ability, isEffect())) { return confirmAction(cost, Localizer.getInstance().getMessage("lblSacrificeCardConfirm", CardTranslation.getTranslatedName(host.getName()))) ? PaymentDecision.card(host) : null; } return null; } + CardCollectionView list = CardLists.filter(player.getCardsIn(ZoneType.Battlefield), CardPredicates.canBeSacrificedBy(ability, isEffect())); + list = CardLists.getValidCards(list, type.split(";"), player, source, ability); + if (amount.equals("All")) { return PaymentDecision.card(list); } @@ -1059,6 +1059,7 @@ public class HumanCostDecision extends CostDecisionMakerBase { if (list.size() < c) { return null; } + final InputSelectCardsFromList inp = new InputSelectCardsFromList(controller, c, c, list, ability); inp.setMessage(Localizer.getInstance().getMessage("lblSelectATargetToSacrifice", cost.getDescriptiveType(), "%d")); inp.setCancelAllowed(!mandatory);