Merge pull request #2100 from tool4ever/somefixes

Improve damage check logic for losing + performance
This commit is contained in:
Anthony Calosa
2022-12-15 07:38:42 +08:00
committed by GitHub
7 changed files with 44 additions and 53 deletions

View File

@@ -814,9 +814,6 @@ public class AiController {
}
public AiPlayDecision canPlaySa(SpellAbility sa) {
final Card card = sa.getHostCard();
final boolean isRightTiming = sa.canCastTiming(player);
if (!checkAiSpecificRestrictions(sa)) {
return AiPlayDecision.CantPlayAi;
}
@@ -824,6 +821,12 @@ public class AiController {
return canPlaySa(((WrappedAbility) sa).getWrappedAbility());
}
if (!sa.canCastTiming(player)) {
return AiPlayDecision.AnotherTime;
}
final Card card = sa.getHostCard();
// Trying to play a card that has Buyback without a Buyback cost, look for possible additional considerations
if (getBooleanProperty(AiProps.TRY_TO_PRESERVE_BUYBACK_SPELLS)) {
if (card.hasKeyword(Keyword.BUYBACK) && !sa.isBuyBackAbility() && !canPlaySpellWithoutBuyback(card, sa)) {
@@ -898,9 +901,6 @@ public class AiController {
return AiPlayDecision.AnotherTime;
}
if (sa instanceof SpellPermanent) {
if (!isRightTiming) {
return AiPlayDecision.AnotherTime;
}
return canPlayFromEffectAI((SpellPermanent)sa, false, true);
}
if (sa.usesTargeting()) {
@@ -912,18 +912,13 @@ public class AiController {
}
}
if (sa instanceof Spell) {
if (ComputerUtil.getDamageForPlaying(player, sa) >= player.getLife()
&& !player.cantLoseForZeroOrLessLife() && player.canLoseLife()) {
if (!player.cantLoseForZeroOrLessLife() && player.canLoseLife() &&
ComputerUtil.getDamageForPlaying(player, sa) >= player.getLife()) {
return AiPlayDecision.CurseEffects;
}
if (!isRightTiming) {
return AiPlayDecision.AnotherTime;
}
return canPlaySpellBasic(card, sa);
}
if (!isRightTiming) {
return AiPlayDecision.AnotherTime;
}
return AiPlayDecision.WillPlay;
}
@@ -1411,8 +1406,8 @@ public class AiController {
if (!checkETBEffects(card, spell, null)) {
return AiPlayDecision.BadEtbEffects;
}
if (damage + ComputerUtil.getDamageFromETB(player, card) >= player.getLife()
&& !player.cantLoseForZeroOrLessLife() && player.canLoseLife()) {
if (!player.cantLoseForZeroOrLessLife() && player.canLoseLife()
&& damage + ComputerUtil.getDamageFromETB(player, card) >= player.getLife()) {
return AiPlayDecision.BadEtbEffects;
}
}
@@ -1496,35 +1491,33 @@ public class AiController {
if (landsWannaPlay != null && !landsWannaPlay.isEmpty()) {
// TODO search for other land it might want to play?
Card land = chooseBestLandToPlay(landsWannaPlay);
if (ComputerUtil.getDamageFromETB(player, land) < player.getLife() || !player.canLoseLife()
|| player.cantLoseForZeroOrLessLife() ) {
if (!game.getPhaseHandler().is(PhaseType.MAIN1) || !isSafeToHoldLandDropForMain2(land)) {
final List<SpellAbility> abilities = Lists.newArrayList();
if ((!player.canLoseLife() || player.cantLoseForZeroOrLessLife() || ComputerUtil.getDamageFromETB(player, land) < player.getLife())
&& (!game.getPhaseHandler().is(PhaseType.MAIN1) || !isSafeToHoldLandDropForMain2(land))) {
final List<SpellAbility> abilities = Lists.newArrayList();
// TODO extend this logic to evaluate MDFC with both sides land
// this can only happen if its a MDFC land
if (!land.isLand()) {
land.setState(CardStateName.Modal, true);
land.setBackSide(true);
}
// TODO extend this logic to evaluate MDFC with both sides land
// this can only happen if its a MDFC land
if (!land.isLand()) {
land.setState(CardStateName.Modal, true);
land.setBackSide(true);
}
LandAbility la = new LandAbility(land, player, null);
LandAbility la = new LandAbility(land, player, null);
la.setCardState(land.getCurrentState());
if (la.canPlay()) {
abilities.add(la);
}
// add mayPlay option
for (CardPlayOption o : land.mayPlay(player)) {
la = new LandAbility(land, player, o.getAbility());
la.setCardState(land.getCurrentState());
if (la.canPlay()) {
abilities.add(la);
}
// add mayPlay option
for (CardPlayOption o : land.mayPlay(player)) {
la = new LandAbility(land, player, o.getAbility());
la.setCardState(land.getCurrentState());
if (la.canPlay()) {
abilities.add(la);
}
}
if (!abilities.isEmpty()) {
return abilities;
}
}
if (!abilities.isEmpty()) {
return abilities;
}
}
}

View File

@@ -100,20 +100,19 @@ public abstract class DamageAiBase extends SpellAbilityAi {
return false;
}
if (!enemy.canLoseLife()) {
return false;
}
if (!noPrevention) {
restDamage = ComputerUtilCombat.predictDamageTo(enemy, restDamage, hostcard, false);
} else {
restDamage = enemy.staticReplaceDamage(restDamage, hostcard, false);
}
if (restDamage == 0) {
return false;
}
if (!enemy.canLoseLife()) {
return false;
}
final CardCollectionView hand = comp.getCardsIn(ZoneType.Hand);
if ((enemy.getLife() - restDamage) < 5) {