mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-12 16:58:57 +00:00
Fix some bad params in AI combat trigger prediction
This commit is contained in:
@@ -691,7 +691,7 @@ public class ComputerUtilCombat {
|
|||||||
if (flankingMagnitude >= blocker.getNetToughness()) {
|
if (flankingMagnitude >= blocker.getNetToughness()) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if ((flankingMagnitude >= (blocker.getNetToughness() - blocker.getDamage()))
|
if (flankingMagnitude >= blocker.getNetToughness() - blocker.getDamage()
|
||||||
&& !blocker.hasKeyword(Keyword.INDESTRUCTIBLE)) {
|
&& !blocker.hasKeyword(Keyword.INDESTRUCTIBLE)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -914,13 +914,6 @@ public class ComputerUtilCombat {
|
|||||||
public static int predictPowerBonusOfBlocker(final Card attacker, final Card blocker, boolean withoutAbilities) {
|
public static int predictPowerBonusOfBlocker(final Card attacker, final Card blocker, boolean withoutAbilities) {
|
||||||
int power = 0;
|
int power = 0;
|
||||||
|
|
||||||
// Apparently, Flanking is predicted below from a trigger, so using the code below results in double
|
|
||||||
// application of power bonus. A bit more testing may be needed though, so commenting out for now.
|
|
||||||
/*
|
|
||||||
if (attacker.hasKeyword("Flanking") && !blocker.hasKeyword("Flanking")) {
|
|
||||||
power -= attacker.getAmountOfKeyword("Flanking");
|
|
||||||
}*/
|
|
||||||
|
|
||||||
// Serene Master switches power with attacker
|
// Serene Master switches power with attacker
|
||||||
if (blocker.getName().equals("Serene Master")) {
|
if (blocker.getName().equals("Serene Master")) {
|
||||||
power += attacker.getNetPower() - blocker.getNetPower();
|
power += attacker.getNetPower() - blocker.getNetPower();
|
||||||
@@ -992,7 +985,7 @@ public class ComputerUtilCombat {
|
|||||||
|
|
||||||
String defined = sa.getParam("Defined");
|
String defined = sa.getParam("Defined");
|
||||||
final List<Card> list = AbilityUtils.getDefinedCards(source, defined, sa);
|
final List<Card> list = AbilityUtils.getDefinedCards(source, defined, sa);
|
||||||
if ("TriggeredBlocker".equals(defined)) {
|
if (defined != null && defined.startsWith("TriggeredBlocker")) {
|
||||||
list.add(blocker);
|
list.add(blocker);
|
||||||
}
|
}
|
||||||
if (!list.contains(blocker)) {
|
if (!list.contains(blocker)) {
|
||||||
@@ -1067,10 +1060,6 @@ public class ComputerUtilCombat {
|
|||||||
public static int predictToughnessBonusOfBlocker(final Card attacker, final Card blocker, boolean withoutAbilities) {
|
public static int predictToughnessBonusOfBlocker(final Card attacker, final Card blocker, boolean withoutAbilities) {
|
||||||
int toughness = 0;
|
int toughness = 0;
|
||||||
|
|
||||||
if (attacker.hasKeyword(Keyword.FLANKING) && !blocker.hasKeyword(Keyword.FLANKING)) {
|
|
||||||
toughness -= attacker.getAmountOfKeyword(Keyword.FLANKING);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (blocker.getName().equals("Shape Stealer")) {
|
if (blocker.getName().equals("Shape Stealer")) {
|
||||||
toughness += attacker.getNetToughness() - blocker.getNetToughness();
|
toughness += attacker.getNetToughness() - blocker.getNetToughness();
|
||||||
}
|
}
|
||||||
@@ -1096,9 +1085,11 @@ public class ComputerUtilCombat {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final String defined = sa.getParam("Defined");
|
||||||
|
|
||||||
// DealDamage triggers
|
// DealDamage triggers
|
||||||
if (ApiType.DealDamage.equals(sa.getApi())) {
|
if (ApiType.DealDamage.equals(sa.getApi())) {
|
||||||
if (!"TriggeredBlocker".equals(sa.getParam("Defined"))) {
|
if (defined == null || !defined.startsWith("TriggeredBlocker")) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
int damage = AbilityUtils.calculateAmount(source, sa.getParam("NumDmg"), sa);
|
int damage = AbilityUtils.calculateAmount(source, sa.getParam("NumDmg"), sa);
|
||||||
@@ -1107,7 +1098,7 @@ public class ComputerUtilCombat {
|
|||||||
|
|
||||||
// -1/-1 PutCounter triggers
|
// -1/-1 PutCounter triggers
|
||||||
if (ApiType.PutCounter.equals(sa.getApi())) {
|
if (ApiType.PutCounter.equals(sa.getApi())) {
|
||||||
if (!"TriggeredBlocker".equals(sa.getParam("Defined"))) {
|
if (defined == null || !defined.startsWith("TriggeredBlocker")) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!"M1M1".equals(sa.getParam("CounterType"))) {
|
if (!"M1M1".equals(sa.getParam("CounterType"))) {
|
||||||
@@ -1121,8 +1112,8 @@ public class ComputerUtilCombat {
|
|||||||
if (sa.usesTargeting()) {
|
if (sa.usesTargeting()) {
|
||||||
continue; // targeted pumping not supported
|
continue; // targeted pumping not supported
|
||||||
}
|
}
|
||||||
final List<Card> list = AbilityUtils.getDefinedCards(source, sa.getParam("Defined"), null);
|
final List<Card> list = AbilityUtils.getDefinedCards(source, defined, null);
|
||||||
if ("TriggeredBlocker".equals(sa.getParam("Defined"))) {
|
if (defined != null && defined.startsWith("TriggeredBlocker")) {
|
||||||
list.add(blocker);
|
list.add(blocker);
|
||||||
}
|
}
|
||||||
if (list.isEmpty() || !list.contains(blocker)) {
|
if (list.isEmpty() || !list.contains(blocker)) {
|
||||||
@@ -1292,7 +1283,7 @@ public class ComputerUtilCombat {
|
|||||||
if (!sa.hasParam("ValidCards")) {
|
if (!sa.hasParam("ValidCards")) {
|
||||||
list = AbilityUtils.getDefinedCards(source, sa.getParam("Defined"), null);
|
list = AbilityUtils.getDefinedCards(source, sa.getParam("Defined"), null);
|
||||||
}
|
}
|
||||||
if (sa.hasParam("Defined") && sa.getParam("Defined").equals("TriggeredAttacker")) {
|
if (sa.hasParam("Defined") && sa.getParam("Defined").startsWith("TriggeredAttacker")) {
|
||||||
list.add(attacker);
|
list.add(attacker);
|
||||||
}
|
}
|
||||||
if (sa.hasParam("ValidCards")) {
|
if (sa.hasParam("ValidCards")) {
|
||||||
@@ -1496,8 +1487,9 @@ public class ComputerUtilCombat {
|
|||||||
if (!sa.hasParam("NumDef")) {
|
if (!sa.hasParam("NumDef")) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
CardCollection list = AbilityUtils.getDefinedCards(source, sa.getParam("Defined"), sa);
|
final String defined = sa.getParam("Defined");
|
||||||
if ("TriggeredAttacker".equals(sa.getParam("Defined"))) {
|
CardCollection list = AbilityUtils.getDefinedCards(source, defined, sa);
|
||||||
|
if (defined != null && defined.startsWith("TriggeredAttacker")) {
|
||||||
list.add(attacker);
|
list.add(attacker);
|
||||||
}
|
}
|
||||||
if (!list.contains(attacker)) {
|
if (!list.contains(attacker)) {
|
||||||
@@ -1637,7 +1629,7 @@ public class ComputerUtilCombat {
|
|||||||
if (!sa.hasParam("Defined")) {
|
if (!sa.hasParam("Defined")) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (sa.getParam("Defined").equals("TriggeredAttacker")) {
|
if (sa.getParam("Defined").startsWith("TriggeredAttacker")) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (sa.getParam("Defined").equals("Self") && source.equals(attacker)) {
|
if (sa.getParam("Defined").equals("Self") && source.equals(attacker)) {
|
||||||
@@ -1891,7 +1883,7 @@ public class ComputerUtilCombat {
|
|||||||
if (!sa.hasParam("Defined")) {
|
if (!sa.hasParam("Defined")) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (sa.getParam("Defined").equals("TriggeredBlocker")) {
|
if (sa.getParam("Defined").startsWith("TriggeredBlocker")) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (sa.getParam("Defined").equals("Self") && source.equals(blocker)) {
|
if (sa.getParam("Defined").equals("Self") && source.equals(blocker)) {
|
||||||
@@ -1940,10 +1932,10 @@ public class ComputerUtilCombat {
|
|||||||
|
|
||||||
if (((blocker.hasKeyword(Keyword.INDESTRUCTIBLE) || (ComputerUtil.canRegenerate(ai, blocker) && !withoutAbilities)) && !(attacker
|
if (((blocker.hasKeyword(Keyword.INDESTRUCTIBLE) || (ComputerUtil.canRegenerate(ai, blocker) && !withoutAbilities)) && !(attacker
|
||||||
.hasKeyword(Keyword.WITHER) || attacker.hasKeyword(Keyword.INFECT)))
|
.hasKeyword(Keyword.WITHER) || attacker.hasKeyword(Keyword.INFECT)))
|
||||||
|| (blocker.hasKeyword(Keyword.PERSIST) && !blocker.canReceiveCounters(CounterEnumType.M1M1) && (blocker
|
|| (blocker.hasKeyword(Keyword.PERSIST) && !blocker.canReceiveCounters(CounterEnumType.M1M1) && blocker
|
||||||
.getCounters(CounterEnumType.M1M1) == 0))
|
.getCounters(CounterEnumType.M1M1) == 0)
|
||||||
|| (blocker.hasKeyword(Keyword.UNDYING) && !blocker.canReceiveCounters(CounterEnumType.P1P1) && (blocker
|
|| (blocker.hasKeyword(Keyword.UNDYING) && !blocker.canReceiveCounters(CounterEnumType.P1P1) && blocker
|
||||||
.getCounters(CounterEnumType.P1P1) == 0))) {
|
.getCounters(CounterEnumType.P1P1) == 0)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2396,9 +2388,9 @@ public class ComputerUtilCombat {
|
|||||||
|
|
||||||
for (Card atk : attackers) {
|
for (Card atk : attackers) {
|
||||||
if (atk.hasKeyword(Keyword.FLYING) || atk.hasKeyword(Keyword.SHADOW)
|
if (atk.hasKeyword(Keyword.FLYING) || atk.hasKeyword(Keyword.SHADOW)
|
||||||
|| atk.hasKeyword(Keyword.HORSEMANSHIP) || (atk.hasKeyword(Keyword.FEAR)
|
|| atk.hasKeyword(Keyword.HORSEMANSHIP) || atk.hasKeyword(Keyword.FEAR)
|
||||||
|| atk.hasKeyword(Keyword.INTIMIDATE) || atk.hasKeyword(Keyword.SKULK)
|
|| atk.hasKeyword(Keyword.INTIMIDATE) || atk.hasKeyword(Keyword.SKULK)
|
||||||
|| atk.hasKeyword(Keyword.PROTECTION))) {
|
|| atk.hasKeyword(Keyword.PROTECTION)) {
|
||||||
withEvasion.add(atk);
|
withEvasion.add(atk);
|
||||||
} else {
|
} else {
|
||||||
withoutEvasion.add(atk);
|
withoutEvasion.add(atk);
|
||||||
|
|||||||
@@ -1554,11 +1554,11 @@ public class AttachAi extends SpellAbilityAi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final boolean evasive = (keyword.equals("Unblockable") || keyword.equals("Fear")
|
final boolean evasive = keyword.equals("Unblockable") || keyword.equals("Fear")
|
||||||
|| keyword.equals("Intimidate") || keyword.equals("Shadow")
|
|| keyword.equals("Intimidate") || keyword.equals("Shadow")
|
||||||
|| keyword.equals("Flying") || keyword.equals("Horsemanship")
|
|| keyword.equals("Flying") || keyword.equals("Horsemanship")
|
||||||
|| keyword.endsWith("walk") || keyword.startsWith("CantBeBlockedBy")
|
|| keyword.endsWith("walk") || keyword.startsWith("CantBeBlockedBy")
|
||||||
|| keyword.equals("All creatures able to block CARDNAME do so."));
|
|| keyword.equals("All creatures able to block CARDNAME do so.");
|
||||||
// give evasive keywords to creatures that can attack and deal damage
|
// give evasive keywords to creatures that can attack and deal damage
|
||||||
|
|
||||||
boolean canBeBlocked = false;
|
boolean canBeBlocked = false;
|
||||||
|
|||||||
@@ -3473,11 +3473,7 @@ public class AbilityUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (value.contains("DamageToOppsThisTurn")) {
|
if (value.contains("DamageToOppsThisTurn")) {
|
||||||
int oppDmg = 0;
|
return doXMath(player.getOpponentsAssignedDamage(), m, source, ctb);
|
||||||
for (Player opp : player.getOpponents()) {
|
|
||||||
oppDmg += opp.getAssignedDamage();
|
|
||||||
}
|
|
||||||
return doXMath(oppDmg, m, source, ctb);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value.contains("NonCombatDamageDealtThisTurn")) {
|
if (value.contains("NonCombatDamageDealtThisTurn")) {
|
||||||
|
|||||||
@@ -5240,9 +5240,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
|||||||
} else {
|
} else {
|
||||||
assignedDamageMap.put(sourceCard, assignedDamageMap.get(sourceCard) + assignedDamage0);
|
assignedDamageMap.put(sourceCard, assignedDamageMap.get(sourceCard) + assignedDamage0);
|
||||||
}
|
}
|
||||||
if (assignedDamage0 > 0) {
|
view.updateAssignedDamage(this);
|
||||||
view.updateAssignedDamage(this);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
public final void clearAssignedDamage() {
|
public final void clearAssignedDamage() {
|
||||||
if (assignedDamageMap.isEmpty()) { return; }
|
if (assignedDamageMap.isEmpty()) { return; }
|
||||||
|
|||||||
@@ -141,8 +141,7 @@ public final class CardUtil {
|
|||||||
for (Player p : game.getPlayers()) {
|
for (Player p : game.getPlayers()) {
|
||||||
res.addAll(p.getZone(to).getCardsAddedLastTurn(from));
|
res.addAll(p.getZone(to).getCardsAddedLastTurn(from));
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
res.addAll(game.getStackZone().getCardsAddedLastTurn(from));
|
res.addAll(game.getStackZone().getCardsAddedLastTurn(from));
|
||||||
}
|
}
|
||||||
return CardLists.getValidCardsAsList(res, valid, src.getController(), src, ctb);
|
return CardLists.getValidCardsAsList(res, valid, src.getController(), src, ctb);
|
||||||
|
|||||||
@@ -12,5 +12,5 @@ ALTERNATE
|
|||||||
Name:Away
|
Name:Away
|
||||||
ManaCost:2 B
|
ManaCost:2 B
|
||||||
Types:Instant
|
Types:Instant
|
||||||
A:SP$ Sacrifice | Cost$ 2 B | ValidTgts$ Player | SacValid$ Creature | SacMessage$ Creature | SpellDescription$ Target Player sacrifices a creature.
|
A:SP$ Sacrifice | Cost$ 2 B | ValidTgts$ Player | SacValid$ Creature | SacMessage$ Creature | SpellDescription$ Target player sacrifices a creature.
|
||||||
Oracle:Target player sacrifices a creature.\nFuse (You may cast one or both halves of this card from your hand.)
|
Oracle:Target player sacrifices a creature.\nFuse (You may cast one or both halves of this card from your hand.)
|
||||||
|
|||||||
Reference in New Issue
Block a user