Skip to content

Commit 0bfb918

Browse files
authored
Clean up (#11188)
1 parent 646d293 commit 0bfb918

10 files changed

Lines changed: 49 additions & 87 deletions

File tree

forge-ai/src/main/java/forge/ai/AiBlockController.java

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -604,6 +604,7 @@ private void makeGangNonLethalBlocks(final Combat combat) {
604604
private void makeTradeBlocks(final Combat combat) {
605605
List<Card> currentAttackers = new ArrayList<>(attackersLeft);
606606
List<Card> killingBlockers;
607+
boolean needsRefresh = false;
607608

608609
for (final Card attacker : attackersLeft) {
609610
if (CombatUtil.getMinNumBlockersForAttacker(attacker, combat.getDefenderPlayerByAttacker(attacker)) > 1) {
@@ -618,19 +619,17 @@ private void makeTradeBlocks(final Combat combat) {
618619

619620
if (!killingBlockers.isEmpty()) {
620621
final Card blocker = ComputerUtilCard.getWorstCreatureAI(killingBlockers);
621-
boolean doTrade = false;
622622

623-
if (lifeInDanger && ComputerUtilCombat.lifeInDanger(ai, combat)) {
624-
// Always trade when life in danger
625-
doTrade = true;
626-
} else {
627-
// Randomly trade creatures with lower power and [hopefully] worse abilities, if enabled in profile
628-
doTrade = wouldLikeToRandomlyTrade(attacker, blocker, combat);
623+
if (lifeInDanger && needsRefresh) {
624+
// is it very likely to end up in danger again if we weren't already?
625+
lifeInDanger = ComputerUtilCombat.lifeInDanger(ai, combat);
629626
}
630627

631-
if (doTrade) {
628+
// Randomly trade creatures with lower power and [hopefully] worse abilities, if enabled in profile
629+
if (lifeInDanger || wouldLikeToRandomlyTrade(attacker, blocker, combat)) {
632630
combat.addBlocker(attacker, blocker);
633631
currentAttackers.remove(attacker);
632+
needsRefresh = true;
634633
}
635634
}
636635
}
@@ -1087,11 +1086,10 @@ private void assignBlockers(final Combat combat, List<Card> possibleBlockers) {
10871086
// When the AI holds some Fog effect, don't bother about lifeInDanger
10881087
if (!ComputerUtil.hasAFogEffect(ai, ai, checkingOther)) {
10891088
lifeInDanger = ComputerUtilCombat.lifeInDanger(ai, combat);
1090-
makeTradeBlocks(combat); // choose necessary trade blocks
1089+
makeTradeBlocks(combat);
10911090

1092-
// if life is still in danger
10931091
if (lifeInDanger) {
1094-
makeChumpBlocks(combat); // choose necessary chump blocks
1092+
makeChumpBlocks(combat);
10951093
}
10961094

10971095
// Reinforce blockers blocking attackers with trample if life is still in danger
@@ -1114,7 +1112,7 @@ private void assignBlockers(final Combat combat, List<Card> possibleBlockers) {
11141112
// == 2. If the AI life would still be in danger make a safer approach ==
11151113
if (lifeInDanger) {
11161114
clearBlockers(combat, possibleBlockers); // reset every block assignment
1117-
makeTradeBlocks(combat); // choose necessary trade blocks
1115+
makeTradeBlocks(combat);
11181116
makeGoodBlocks(combat);
11191117
// choose necessary chump blocks if life is still in danger
11201118
makeChumpBlocks(combat);

forge-ai/src/main/java/forge/ai/ability/AnimateAi.java

Lines changed: 26 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
import forge.game.ability.ApiType;
1313
import forge.game.ability.effects.AnimateEffectBase;
1414
import forge.game.card.*;
15-
import forge.game.combat.Combat;
1615
import forge.game.cost.Cost;
1716
import forge.game.cost.CostPutCounter;
1817
import forge.game.keyword.Keyword;
@@ -357,10 +356,13 @@ private AiAbilityDecision animateTgtAI(final SpellAbility sa) {
357356
// check if its Permanent or that creature would attack
358357
if (ph.isPlayerTurn(ai)) {
359358
if (!"Permanent".equals(sa.getParam("Duration"))
360-
&& !ComputerUtilCard.doesSpecifiedCreatureAttackAI(ai, animatedCopy)
361-
&& !"UntilHostLeavesPlay".equals(sa.getParam("Duration"))) {
359+
&& !"UntilHostLeavesPlay".equals(sa.getParam("Duration"))
360+
&& !ComputerUtilCard.doesSpecifiedCreatureAttackAI(ai, animatedCopy)) {
362361
continue;
363362
}
363+
} else if (ph.inCombat() && game.getCombat().getDefendingPlayers().contains(ai)
364+
&& !ComputerUtilCard.doesSpecifiedCreatureBlock(ai, animatedCopy)) {
365+
continue;
364366
}
365367

366368
// store in map
@@ -399,54 +401,10 @@ private AiAbilityDecision animateTgtAI(final SpellAbility sa) {
399401
sa.getTargets().add(worst);
400402
}
401403
return new AiAbilityDecision(100, AiPlayDecision.WillPlay);
402-
}
403-
404-
if (logic.equals("SetPT")) {
405-
// TODO: 1. Teach the AI to use this to save the creature from direct damage;
406-
// 2. Determine the best target in a smarter way?
407-
Card worst = ComputerUtilCard.getWorstCreatureAI(ai.getCreaturesInPlay());
408-
Card buffed = becomeAnimated(worst, sa);
409-
410-
if (ComputerUtilCard.doesSpecifiedCreatureAttackAI(ai, buffed)
411-
&& (buffed.getNetPower() - worst.getNetPower() >= 3 || !ComputerUtilCard.doesCreatureAttackAI(ai, worst))) {
412-
sa.getTargets().add(worst);
413-
rememberAnimatedThisTurn(ai, worst);
414-
return new AiAbilityDecision(100, AiPlayDecision.WillPlay);
415-
}
416-
}
417-
418-
if (logic.equals("ValuableAttackerOrBlocker")) {
419-
final Combat combat = ph.getCombat();
420-
for (Card c : list) {
421-
Card animated = becomeAnimated(c, sa);
422-
boolean isValuableAttacker = ph.is(PhaseType.COMBAT_BEGIN, ai) && ComputerUtilCard.doesSpecifiedCreatureAttackAI(ai, animated);
423-
boolean isValuableBlocker = combat != null && combat.getDefendingPlayers().contains(ai) && ComputerUtilCard.doesSpecifiedCreatureBlock(ai, animated);
424-
if (isValuableAttacker || isValuableBlocker)
425-
return new AiAbilityDecision(100, AiPlayDecision.WillPlay);
426-
}
427-
}
428-
429-
if (logic.equals("Worst")) {
430-
Card worst = ComputerUtilCard.getWorstPermanentAI(list, false, false, false, false);
431-
if(worst != null) {
432-
sa.getTargets().add(worst);
433-
rememberAnimatedThisTurn(ai, worst);
434-
return new AiAbilityDecision(100, AiPlayDecision.WillPlay);
435-
}
436-
}
437-
438-
if (sa.hasParam("AITgts") && !list.isEmpty()) {
439-
//No logic, but we do have preferences. Pick the best among those?
440-
Card best = ComputerUtilCard.getBestAI(list);
441-
sa.getTargets().add(best);
442-
rememberAnimatedThisTurn(ai, best);
443-
return new AiAbilityDecision(100, AiPlayDecision.WillPlay);
444-
}
445-
446-
// Pure P/T-setting effect without type or ability changes (e.g. Genemorph Imago):
447-
// buff own creatures that actually gain from it, or shrink an opponent's
448-
if (logic.isEmpty() && sa.hasParam("Power") && sa.hasParam("Toughness")
449-
&& !sa.hasParam("Types") && !sa.hasParam("Keywords") && !sa.hasParam("Abilities")) {
404+
} else if (logic.isEmpty() && sa.hasParam("Power") && sa.hasParam("Toughness")
405+
&& !sa.hasParam("Keywords") && !sa.hasParam("Abilities")) {
406+
// Pure P/T-setting effect without card type or ability changes (e.g. Genemorph Imago):
407+
// buff own creatures that actually gain from it, or shrink an opponent's
450408
Card best = null;
451409
int bestGain = 0;
452410
for (final Card c : list) {
@@ -472,6 +430,23 @@ private AiAbilityDecision animateTgtAI(final SpellAbility sa) {
472430
return new AiAbilityDecision(0, AiPlayDecision.TargetingFailed);
473431
}
474432

433+
if (logic.equals("Worst")) {
434+
Card worst = ComputerUtilCard.getWorstPermanentAI(list, false, false, false, false);
435+
if (worst != null) {
436+
sa.getTargets().add(worst);
437+
rememberAnimatedThisTurn(ai, worst);
438+
return new AiAbilityDecision(100, AiPlayDecision.WillPlay);
439+
}
440+
}
441+
442+
if (sa.hasParam("AITgts") && !list.isEmpty()) {
443+
//No logic, but we do have preferences. Pick the best among those?
444+
Card best = ComputerUtilCard.getBestAI(list);
445+
sa.getTargets().add(best);
446+
rememberAnimatedThisTurn(ai, best);
447+
return new AiAbilityDecision(100, AiPlayDecision.WillPlay);
448+
}
449+
475450
// This is reasonable for now. Kamahl, Fist of Krosa and a sorcery or
476451
// two are the only things
477452
// that animate a target. Those can just use AI:RemoveDeck:All until

forge-game/src/main/java/forge/game/ability/effects/CharmEffect.java

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -240,18 +240,13 @@ public static boolean makeChoices(SpellAbility sa) {
240240
}
241241

242242
if (sa.hasParam("Random")) {
243+
boolean random = true;
243244
if (sa.getParam("Random").equals("Compare")) {
244-
// RandomCompareSVar$ Y | RandomCompare$ LT1
245-
String svar = sa.getParam("RandomCompareSVar");
246245
String compare = sa.getParam("RandomCompare");
247-
int value = AbilityUtils.calculateAmount(source, sa.getSVar(svar), sa);
248-
249-
if (Expressions.compare(value, compare.substring(0, 2), Integer.parseInt(compare.substring(2)))) {
250-
// If we don't meet the condition, let the player choose
251-
chainAbilities(sa, Aggregates.random(choices, num));
252-
return true;
253-
}
254-
} else {
246+
int value = AbilityUtils.calculateAmount(source, sa.getParam("RandomCompareSVar"), sa);
247+
random = Expressions.compare(value, compare.substring(0, 2), Integer.parseInt(compare.substring(2)));
248+
}
249+
if (random) {
255250
chainAbilities(sa, Aggregates.random(choices, num));
256251
return true;
257252
}

forge-game/src/main/java/forge/game/player/PlayerController.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ public enum BinaryChoiceType {
6262
public enum FullControlFlag {
6363
ChooseCostOrder,
6464
ChooseCostReductionOrderAndVariableAmount,
65-
ChooseManaPoolShard, // select shard with special properties //TODO: UI option to enable this one
65+
ChooseManaPoolShard, // select shard with special properties
6666
NoPaymentFromManaAbility,
6767
NoFreeCombatCostHandling,
6868
AllowPaymentStartWithMissingResources,

forge-game/src/main/java/forge/game/spellability/AbilityManaPart.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@
6666
* @version $Id$
6767
*/
6868
public class AbilityManaPart implements java.io.Serializable {
69-
/** Constant <code>serialVersionUID=-6816356991224950520L</code>. */
69+
7070
private static final long serialVersionUID = -6816356991224950520L;
7171

7272
private final String origProduced;

forge-gui-desktop/src/main/java/forge/view/arcane/CardPanel.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -441,7 +441,6 @@ protected final void paintChildren(final Graphics g) {
441441
FSkin.drawImage(g, FSkin.getIcon(FSkinProp.ICO_PADLOCK), cardXOffset, cardYOffset, cardWidth, cardHeight);
442442
}
443443
}
444-
445444
}
446445
displayIconOverlay(g, canShow);
447446
if (groupCount >= 2) {
@@ -677,7 +676,6 @@ private void displayIconOverlay(final Graphics g, final boolean canShow) {
677676
}
678677

679678
if (card.getCounters() != null && !card.getCounters().isEmpty()) {
680-
681679
switch (CounterDisplayType.from(FModel.getPreferences().getPref(FPref.UI_CARD_COUNTER_DISPLAY_TYPE))) {
682680
case OLD_WHEN_SMALL:
683681
case TEXT:
@@ -691,7 +689,6 @@ private void displayIconOverlay(final Graphics g, final boolean canShow) {
691689
drawCounterTabs(g);
692690
break;
693691
}
694-
695692
}
696693

697694
if(card.getMarkerText() != null) {
@@ -852,7 +849,6 @@ private void drawCounterTabs(final Graphics g) {
852849
drawVerticallyCenteredString(g, String.valueOf(numberOfCounters), numberBounds, largeCounterFont, largeFontMetrics);
853850

854851
}
855-
856852
}
857853

858854
private void drawCounterImage(final Graphics g) {

forge-gui/res/cardsfolder/m/minsc_beloved_ranger.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Types:Legendary Creature Human Ranger
44
PT:3/3
55
T:Mode$ ChangesZone | ValidCard$ Card.Self | Origin$ Any | Destination$ Battlefield | Execute$ TrigMinsc | TriggerDescription$ When CARDNAME enters, create Boo, a legendary 1/1 red Hamster creature token with trample and haste.
66
SVar:TrigMinsc:DB$ Token | TokenScript$ boo | TokenOwner$ You
7-
A:AB$ Animate | Cost$ X | Power$ X | Toughness$ X | ValidTgts$ Creature.YouCtrl | TgtPrompt$ Select target creature you control | Types$ Giant | SorcerySpeed$ True | AILogic$ SetPT | SpellDescription$ Until end of turn, target creature you control has base power and toughness X/X and becomes a Giant in addition to its other types. Activate only as a sorcery.
7+
A:AB$ Animate | Cost$ X | Power$ X | Toughness$ X | ValidTgts$ Creature.YouCtrl | TgtPrompt$ Select target creature you control | Types$ Giant | SorcerySpeed$ True | SpellDescription$ Until end of turn, target creature you control has base power and toughness X/X and becomes a Giant in addition to its other types. Activate only as a sorcery.
88
SVar:X:Count$xPaid
99
DeckHas:Ability$Token
1010
Oracle:When Minsc, Beloved Ranger enters, create Boo, a legendary 1/1 red Hamster creature token with trample and haste.\n{X}: Until end of turn, target creature you control has base power and toughness X/X and becomes a Giant in addition to its other types. Activate only as a sorcery.

forge-gui/res/cardsfolder/t/tough_cookie.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Types:Artifact Creature Food Golem
44
PT:2/2
55
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigFood | TriggerDescription$ When CARDNAME enters, create a Food token. (It's an artifact with "{2}, {T}, Sacrifice this token: You gain 3 life.")
66
SVar:TrigFood:DB$ Token | TokenScript$ c_a_food_sac | TokenOwner$ You
7-
A:AB$ Animate | Cost$ 2 G | ValidTgts$ Artifact.nonCreature+YouCtrl | TgtPrompt$ Select target noncreature artifact you control | Power$ 4 | Toughness$ 4 | Types$ Artifact,Creature | AILogic$ ValuableAttackerOrBlocker | SpellDescription$ Target noncreature artifact you control becomes a 4/4 artifact creature until end of turn.
7+
A:AB$ Animate | Cost$ 2 G | ValidTgts$ Artifact.nonCreature+YouCtrl | TgtPrompt$ Select target noncreature artifact you control | Power$ 4 | Toughness$ 4 | Types$ Artifact,Creature | SpellDescription$ Target noncreature artifact you control becomes a 4/4 artifact creature until end of turn.
88
A:AB$ GainLife | Cost$ 2 T Sac<1/CARDNAME> | LifeAmount$ 3 | SpellDescription$ You gain 3 life.
99
DeckHas:Ability$LifeGain|Sacrifice|Token & Type$Food
1010
DeckHints:Type$Artifact

forge-gui/res/cardsfolder/v/verazol_the_split_current.txt

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,7 @@ PT:0/0
55
K:etbCounter:P1P1:Y:no Condition:CARDNAME enters with a +1/+1 counter on it for each mana spent to cast it.
66
SVar:X:Count$xPaid
77
SVar:Y:Count$CastTotalManaSpent
8-
T:Mode$ SpellCast | ValidSA$ Spell.Kicked | ValidActivatingPlayer$ You | Execute$ DBRemoveCounters | TriggerZones$ Battlefield | OptionalDecider$ You | TriggerDescription$ Whenever you cast a kicked spell, you may remove two +1/+1 counters from NICKNAME. If you do, copy that spell. You may choose new targets for that copy. (A copy of a permanent spell becomes a token.)
9-
SVar:DBRemoveCounters:DB$ RemoveCounter | CounterType$ P1P1 | CounterNum$ 2 | RememberRemoved$ True | SubAbility$ DBCopy
10-
SVar:DBCopy:DB$ CopySpellAbility | ConditionCheckSVar$ Z | SubAbility$ DBCleanup | Defined$ TriggeredSpellAbility | AILogic$ Always | MayChooseTarget$ True
11-
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
12-
SVar:Z:Count$RememberedSize
8+
T:Mode$ SpellCast | ValidSA$ Spell.Kicked | ValidActivatingPlayer$ You | Execute$ TrigCopy | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast a kicked spell, you may remove two +1/+1 counters from NICKNAME. If you do, copy that spell. You may choose new targets for that copy. (A copy of a permanent spell becomes a token.)
9+
SVar:TrigCopy:DB$ CopySpellAbility | Cost$ SubCounter<2/P1P1> | Defined$ TriggeredSpellAbility | AILogic$ Always | MayChooseTarget$ True
1310
DeckHas:Ability$Counters
1411
Oracle:Verazol, the Split Current enters with a +1/+1 counter on it for each mana spent to cast it.\nWhenever you cast a kicked spell, you may remove two +1/+1 counters from Verazol. If you do, copy that spell. You may choose new targets for the copy. (A copy of a permanent spell becomes a token.)

forge-gui/src/main/java/forge/player/PlayerControllerHuman.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1301,6 +1301,7 @@ protected boolean hasEnoughTargets() {
13011301
public Mana chooseManaFromPool(final List<Mana> manaChoices) {
13021302
if (!isFullControl(FullControlFlag.ChooseManaPoolShard))
13031303
return manaChoices.get(0);
1304+
// TODO check if there are any special properties?
13041305
final List<String> options = Lists.newArrayList();
13051306
for (int i = 0; i < manaChoices.size(); i++) {
13061307
final Mana m = manaChoices.get(i);
@@ -1590,7 +1591,7 @@ public void pushActionableCards(boolean paymentMode) {
15901591

15911592
private boolean cardHasPlayableManaAbility(Card c) {
15921593
for (SpellAbility sa : c.getAllPossibleAbilities(player, true)) {
1593-
if (sa.isManaAbility() && sa.canPlay()) return true;
1594+
if (sa.isManaAbility()) return true;
15941595
}
15951596
return false;
15961597
}

0 commit comments

Comments
 (0)